[ Index ]
 

Code source de Mantis 1.1.0rc3

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/core/ -> bug_api.php (source)

   1  <?php
   2  # Mantis - a php based bugtracking system
   3  
   4  # Copyright (C) 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
   5  # Copyright (C) 2002 - 2007  Mantis Team   - mantisbt-dev@lists.sourceforge.net
   6  
   7  # Mantis is free software: you can redistribute it and/or modify
   8  # it under the terms of the GNU General Public License as published by
   9  # the Free Software Foundation, either version 2 of the License, or
  10  # (at your option) any later version.
  11  #
  12  # Mantis is distributed in the hope that it will be useful,
  13  # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15  # GNU General Public License for more details.
  16  #
  17  # You should have received a copy of the GNU General Public License
  18  # along with Mantis.  If not, see <http://www.gnu.org/licenses/>.
  19  
  20      # --------------------------------------------------------
  21      # $Id: bug_api.php,v 1.111.2.1 2007-10-13 22:35:13 giallu Exp $
  22      # --------------------------------------------------------
  23  
  24      $t_core_dir = dirname( __FILE__ ).DIRECTORY_SEPARATOR;
  25  
  26      require_once ( $t_core_dir . 'history_api.php' );
  27      require_once ( $t_core_dir . 'email_api.php' );
  28      require_once ( $t_core_dir . 'bugnote_api.php' );
  29      require_once ( $t_core_dir . 'file_api.php' );
  30      require_once ( $t_core_dir . 'string_api.php' );
  31      require_once ( $t_core_dir . 'sponsorship_api.php' );
  32      require_once ( $t_core_dir . 'twitter_api.php' );
  33      require_once ( $t_core_dir . 'tag_api.php' );
  34  
  35      # MASC RELATIONSHIP
  36      require_once ( $t_core_dir.'relationship_api.php' );
  37      # MASC RELATIONSHIP
  38  
  39      ### Bug API ###
  40  
  41      #===================================
  42      # Bug Data Structure Definition
  43      #===================================
  44      class BugData {
  45          var $project_id = null;
  46          var $reporter_id = 0;
  47          var $handler_id = 0;
  48          var $duplicate_id = 0;
  49          var $priority = NORMAL;
  50          var $severity = MINOR;
  51          var $reproducibility = 10;
  52          var $status = NEW_;
  53          var $resolution = OPEN;
  54          var $projection = 10;
  55          var $category = '';
  56          var $date_submitted = '';
  57          var $last_updated = '';
  58          var $eta = 10;
  59          var $os = '';
  60          var $os_build = '';
  61          var $platform = '';
  62          var $version = '';
  63          var $fixed_in_version = '';
  64          var $target_version = '';
  65          var $build = '';
  66          var $view_state = VS_PUBLIC;
  67          var $summary = '';
  68          var $sponsorship_total = 0;
  69          var $sticky = 0;
  70  
  71          # omitted:
  72          # var $bug_text_id
  73          var $profile_id;
  74  
  75          # extended info
  76          var $description = '';
  77          var $steps_to_reproduce = '';
  78          var $additional_information = '';
  79          
  80          #internal helper objects
  81          var $_stats = null;
  82      }
  83  
  84      #===================================
  85      # Caching
  86      #===================================
  87  
  88      #########################################
  89      # SECURITY NOTE: cache globals are initialized here to prevent them
  90      #   being spoofed if register_globals is turned on
  91  
  92      $g_cache_bug = array();
  93      $g_cache_bug_text = array();
  94  
  95      # --------------------
  96      # Cache an object as a bug.
  97  	function bug_cache_database_result( $p_bug_datebase_result, $p_stats = null ) {
  98          global $g_cache_bug;
  99          
 100          if ( isset( $g_cache_bug[ $p_bug_datebase_result['id'] ] ) ) {
 101              return $g_cache_bug[ $p_bug_datebase_result['id'] ];
 102          }    
 103          
 104          if( !is_int( $p_bug_datebase_result['date_submitted'] ) )
 105              $p_bug_datebase_result['date_submitted']    = db_unixtimestamp( $p_bug_datebase_result['date_submitted']['date_submitted'] );
 106          if( !is_int( $p_bug_datebase_result['last_updated'] ) )
 107              $p_bug_datebase_result['last_updated']    = db_unixtimestamp( $p_bug_datebase_result['last_updated'] );
 108          $g_cache_bug[ $p_bug_datebase_result['id'] ] = $p_bug_datebase_result;
 109          if( !is_null( $p_stats ) ) {
 110              $g_cache_bug[ $p_bug_datebase_result['id'] ]['_stats'] = $p_stats;
 111          }
 112      }
 113  
 114      # --------------------
 115      # Cache a bug row if necessary and return the cached copy
 116      #  If the second parameter is true (default), trigger an error
 117      #  if the bug can't be found.  If the second parameter is
 118      #  false, return false if the bug can't be found.
 119  	function bug_cache_row( $p_bug_id, $p_trigger_errors=true ) {
 120          global $g_cache_bug;
 121  
 122          if ( isset( $g_cache_bug[$p_bug_id] ) ) {
 123              return $g_cache_bug[$p_bug_id];
 124          }
 125  
 126          $c_bug_id        = db_prepare_int( $p_bug_id );
 127          $t_bug_table    = config_get( 'mantis_bug_table' );
 128  
 129          $query = "SELECT *
 130                    FROM $t_bug_table
 131                    WHERE id='$c_bug_id'";
 132          $result = db_query( $query );
 133  
 134          if ( 0 == db_num_rows( $result ) ) {
 135              $g_cache_bug[$c_bug_id] = false;
 136  
 137              if ( $p_trigger_errors ) {
 138                  error_parameters( $p_bug_id );
 139                  trigger_error( ERROR_BUG_NOT_FOUND, ERROR );
 140              } else {
 141                  return false;
 142              }
 143          }
 144  
 145          $row = db_fetch_array( $result );
 146          $row['date_submitted']    = db_unixtimestamp( $row['date_submitted'] );
 147          $row['last_updated']    = db_unixtimestamp( $row['last_updated'] );
 148          $g_cache_bug[$c_bug_id] = $row;
 149  
 150          return $row;
 151      }
 152  
 153      # --------------------
 154      # Inject a bug into the bug cache
 155  	function bug_add_to_cache( $p_bug_row ) {
 156          global $g_cache_bug;
 157  
 158          if ( !is_array( $p_bug_row ) )
 159              return false;
 160  
 161          $c_bug_id = db_prepare_int( $p_bug_row['id'] );
 162          $g_cache_bug[ $c_bug_id ] = $p_bug_row;
 163  
 164          return true;
 165      }
 166  
 167      # --------------------
 168      # Clear the bug cache (or just the given id if specified)
 169  	function bug_clear_cache( $p_bug_id = null ) {
 170          global $g_cache_bug;
 171  
 172          if ( null === $p_bug_id ) {
 173              $g_cache_bug = array();
 174          } else {
 175              $c_bug_id = db_prepare_int( $p_bug_id );
 176              unset( $g_cache_bug[$c_bug_id] );
 177          }
 178  
 179          return true;
 180      }
 181  
 182      # --------------------
 183      # Cache a bug text row if necessary and return the cached copy
 184      #  If the second parameter is true (default), trigger an error
 185      #  if the bug text can't be found.  If the second parameter is
 186      #  false, return false if the bug text can't be found.
 187  	function bug_text_cache_row( $p_bug_id, $p_trigger_errors=true ) {
 188          global $g_cache_bug_text;
 189  
 190          $c_bug_id            = db_prepare_int( $p_bug_id );
 191          $t_bug_table        = config_get( 'mantis_bug_table' );
 192          $t_bug_text_table    = config_get( 'mantis_bug_text_table' );
 193  
 194          if ( isset ( $g_cache_bug_text[$c_bug_id] ) ) {
 195              return $g_cache_bug_text[$c_bug_id];
 196          }
 197  
 198          $query = "SELECT bt.*
 199                    FROM $t_bug_text_table bt, $t_bug_table b
 200                    WHERE b.id='$c_bug_id' AND
 201                            b.bug_text_id = bt.id";
 202          $result = db_query( $query );
 203  
 204          if ( 0 == db_num_rows( $result ) ) {
 205              $g_cache_bug_text[$c_bug_id] = false;
 206  
 207              if ( $p_trigger_errors ) {
 208                  error_parameters( $p_bug_id );
 209                  trigger_error( ERROR_BUG_NOT_FOUND, ERROR );
 210              } else {
 211                  return false;
 212              }
 213          }
 214  
 215          $row = db_fetch_array( $result );
 216  
 217          $g_cache_bug_text[$c_bug_id] = $row;
 218  
 219          return $row;
 220      }
 221  
 222      # --------------------
 223      # Clear the bug text cache (or just the given id if specified)
 224  	function bug_text_clear_cache( $p_bug_id = null ) {
 225          global $g_cache_bug_text;
 226  
 227          if ( null === $p_bug_id ) {
 228              $g_cache_bug_text = array();
 229          } else {
 230              $c_bug_id = db_prepare_int( $p_bug_id );
 231              unset( $g_cache_bug_text[$c_bug_id] );
 232          }
 233  
 234          return true;
 235      }
 236  
 237      #===================================
 238      # Boolean queries and ensures
 239      #===================================
 240  
 241      # --------------------
 242      # check to see if bug exists by id
 243      # return true if it does, false otherwise
 244  	function bug_exists( $p_bug_id ) {
 245          if ( false == bug_cache_row( $p_bug_id, false ) ) {
 246              return false;
 247          } else {
 248              return true;
 249          }
 250      }
 251  
 252      # --------------------
 253      # check to see if bug exists by id
 254      # if it doesn't exist then error
 255      #  otherwise let execution continue undisturbed
 256  	function bug_ensure_exists( $p_bug_id ) {
 257          if ( !bug_exists( $p_bug_id ) ) {
 258              error_parameters( $p_bug_id );
 259              trigger_error( ERROR_BUG_NOT_FOUND, ERROR );
 260          }
 261      }
 262  
 263      # --------------------
 264      # check if the given user is the reporter of the bug
 265      # return true if the user is the reporter, false otherwise
 266  	function bug_is_user_reporter( $p_bug_id, $p_user_id ) {
 267          if ( bug_get_field( $p_bug_id, 'reporter_id' ) == $p_user_id ) {
 268              return true;
 269          } else {
 270              return false;
 271          }
 272      }
 273  
 274      # --------------------
 275      # check if the given user is the handler of the bug
 276      # return true if the user is the handler, false otherwise
 277  	function bug_is_user_handler( $p_bug_id, $p_user_id ) {
 278          if ( bug_get_field( $p_bug_id, 'handler_id' ) == $p_user_id ) {
 279              return true;
 280          } else {
 281              return false;
 282          }
 283      }
 284  
 285      # --------------------
 286      # Check if the bug is readonly and shouldn't be modified
 287      # For a bug to be readonly the status has to be >= bug_readonly_status_threshold and
 288      # current user access level < update_readonly_bug_threshold.
 289  	function bug_is_readonly( $p_bug_id ) {
 290          $t_status = bug_get_field( $p_bug_id, 'status' );
 291          if ( $t_status < config_get( 'bug_readonly_status_threshold' ) ) {
 292              return false;
 293          }
 294  
 295          if ( access_has_bug_level( config_get( 'update_readonly_bug_threshold' ), $p_bug_id ) ) {
 296              return false;
 297          }
 298  
 299          return true;
 300      }
 301  
 302      # --------------------
 303      # Check if the bug is resolved
 304  	function bug_is_resolved( $p_bug_id ) {
 305          $t_status = bug_get_field( $p_bug_id, 'status' );
 306          return ( $t_status >= config_get( 'bug_resolved_status_threshold' ) );
 307      }
 308  
 309      # --------------------
 310      # Validate workflow state to see if bug can be moved to requested state
 311  	function bug_check_workflow( $p_bug_status, $p_wanted_status ) {
 312          $t_status_enum_workflow = config_get( 'status_enum_workflow' );
 313  
 314          if ( count( $t_status_enum_workflow ) < 1) {
 315              # workflow not defined, use default enum
 316              return true;
 317          } else if ( $p_bug_status == $p_wanted_status ) {
 318              # no change in state, allow the transition
 319              return true;
 320          } else {
 321              # workflow defined - find allowed states
 322              $t_allowed_states = $t_status_enum_workflow[$p_bug_status];
 323              $t_arr = explode_enum_string( $t_allowed_states );
 324  
 325              $t_enum_count = count( $t_arr );
 326  
 327              for ( $i = 0; $i < $t_enum_count; $i++ ) {
 328                  # check if wanted status is allowed
 329                  $t_elem  = explode_enum_arr( $t_arr[$i] );
 330                  if ( $p_wanted_status == $t_elem[0] ) {
 331                      return true;
 332                  }
 333              } # end for
 334          }
 335  
 336          return false;
 337      }
 338  
 339      #===================================
 340      # Creation / Deletion / Updating
 341      #===================================
 342  
 343      # --------------------
 344      # Create a new bug and return the bug id
 345      #
 346  	function bug_create( $p_bug_data ) {
 347  
 348          $c_summary                = db_prepare_string( $p_bug_data->summary );
 349          $c_description            = db_prepare_string( $p_bug_data->description );
 350          $c_project_id            = db_prepare_int( $p_bug_data->project_id );
 351          $c_reporter_id            = db_prepare_int( $p_bug_data->reporter_id );
 352          $c_handler_id            = db_prepare_int( $p_bug_data->handler_id );
 353          $c_priority                = db_prepare_int( $p_bug_data->priority );
 354          $c_severity                = db_prepare_int( $p_bug_data->severity );
 355          $c_reproducibility        = db_prepare_int( $p_bug_data->reproducibility );
 356          $c_category                = db_prepare_string( $p_bug_data->category );
 357          $c_os                    = db_prepare_string( $p_bug_data->os );
 358          $c_os_build                = db_prepare_string( $p_bug_data->os_build );
 359          $c_platform                = db_prepare_string( $p_bug_data->platform );
 360          $c_version                = db_prepare_string( $p_bug_data->version );
 361          $c_build                = db_prepare_string( $p_bug_data->build );
 362          $c_profile_id            = db_prepare_int( $p_bug_data->profile_id );
 363          $c_view_state            = db_prepare_int( $p_bug_data->view_state );
 364          $c_steps_to_reproduce    = db_prepare_string( $p_bug_data->steps_to_reproduce );
 365          $c_additional_info        = db_prepare_string( $p_bug_data->additional_information );
 366          $c_sponsorship_total     = 0;
 367          $c_sticky                 = 0;
 368  
 369          # Summary cannot be blank
 370          if ( is_blank( $c_summary ) ) {
 371              error_parameters( lang_get( 'summary' ) );
 372              trigger_error( ERROR_EMPTY_FIELD, ERROR );
 373          }
 374  
 375          # Description cannot be blank
 376          if ( is_blank( $c_description ) ) {
 377              error_parameters( lang_get( 'description' ) );
 378              trigger_error( ERROR_EMPTY_FIELD, ERROR );
 379          }
 380          
 381          if ( is_blank( $c_category ) ) {
 382              error_parameters( lang_get( 'category' ) );
 383              trigger_error( ERROR_EMPTY_FIELD, ERROR );
 384          }
 385  
 386          # Only set target_version if user has access to do so
 387          if ( access_has_project_level( config_get( 'roadmap_update_threshold' ) ) ) {
 388              $c_target_version    = db_prepare_string( $p_bug_data->target_version );
 389          } else { 
 390              $c_target_version    = '';
 391          }
 392  
 393          $t_bug_table                = config_get( 'mantis_bug_table' );
 394          $t_bug_text_table            = config_get( 'mantis_bug_text_table' );
 395          $t_project_category_table    = config_get( 'mantis_project_category_table' );
 396  
 397          # Insert text information
 398          $query = "INSERT INTO $t_bug_text_table
 399                      ( description, steps_to_reproduce, additional_information )
 400                    VALUES
 401                      ( '$c_description', '$c_steps_to_reproduce',
 402                        '$c_additional_info' )";
 403          db_query( $query );
 404  
 405          # Get the id of the text information we just inserted
 406          # NOTE: this is guarranteed to be the correct one.
 407          # The value LAST_INSERT_ID is stored on a per connection basis.
 408  
 409          $t_text_id = db_insert_id($t_bug_text_table);
 410  
 411          # check to see if we want to assign this right off
 412          $t_status = config_get( 'bug_submit_status' );
 413  
 414          # if not assigned, check if it should auto-assigned.
 415          if ( 0 == $c_handler_id ) {
 416              # if a default user is associated with the category and we know at this point
 417              # that that the bug was not assigned to somebody, then assign it automatically.
 418              $query = "SELECT user_id
 419                        FROM $t_project_category_table
 420                        WHERE project_id='$c_project_id' AND category='$c_category'";
 421              $result = db_query( $query );
 422  
 423              if ( db_num_rows( $result ) > 0 ) {
 424                  $c_handler_id = $p_handler_id = db_result( $result );
 425              }
 426          }
 427  
 428          # Check if bug was pre-assigned or auto-assigned.
 429          if ( ( $c_handler_id != 0 ) && ( ON == config_get( 'auto_set_status_to_assigned' ) ) ) {
 430              $t_status = config_get( 'bug_assigned_status' );
 431          }
 432  
 433          # Insert the rest of the data
 434          $t_resolution = OPEN;
 435  
 436          $query = "INSERT INTO $t_bug_table
 437                      ( project_id,
 438                        reporter_id, handler_id,
 439                        duplicate_id, priority,
 440                        severity, reproducibility,
 441                        status, resolution,
 442                        projection, category,
 443                        date_submitted, last_updated,
 444                        eta, bug_text_id,
 445                        os, os_build,
 446                        platform, version,
 447                        build,
 448                        profile_id, summary, view_state, sponsorship_total, sticky, fixed_in_version,
 449                        target_version 
 450                      )
 451                    VALUES
 452                      ( '$c_project_id',
 453                        '$c_reporter_id', '$c_handler_id',
 454                        '0', '$c_priority',
 455                        '$c_severity', '$c_reproducibility',
 456                        '$t_status', '$t_resolution',
 457                        10, '$c_category',
 458                        " . db_now() . "," . db_now() . ",
 459                        10, '$t_text_id',
 460                        '$c_os', '$c_os_build',
 461                        '$c_platform', '$c_version',
 462                        '$c_build',
 463                        '$c_profile_id', '$c_summary', '$c_view_state', '$c_sponsorship_total', '$c_sticky', '',
 464                        '$c_target_version'
 465                      )";
 466          db_query( $query );
 467  
 468          $t_bug_id = db_insert_id($t_bug_table);
 469  
 470          # log new bug
 471          history_log_event_special( $t_bug_id, NEW_BUG );
 472  
 473          # log changes, if any (compare happens in history_log_event_direct)
 474          history_log_event_direct( $t_bug_id, 'status', config_get( 'bug_submit_status' ), $t_status );
 475          history_log_event_direct( $t_bug_id, 'handler_id', 0, $c_handler_id );
 476  
 477          return $t_bug_id;
 478      }
 479  
 480      # --------------------
 481      # Copy a bug from one project to another. Also make copies of issue notes, attachments, history,
 482      # email notifications etc.
 483      # @@@ Not managed FTP file upload
 484      # MASC RELATIONSHIP
 485  	function bug_copy( $p_bug_id, $p_target_project_id = null, $p_copy_custom_fields = false, $p_copy_relationships = false,
 486          $p_copy_history = false, $p_copy_attachments = false, $p_copy_bugnotes = false, $p_copy_monitoring_users = false ) {
 487          global $g_db;
 488  
 489          $t_mantis_custom_field_string_table    = config_get( 'mantis_custom_field_string_table' );
 490          $t_mantis_bug_file_table            = config_get( 'mantis_bug_file_table' );
 491          $t_mantis_bugnote_table                = config_get( 'mantis_bugnote_table' );
 492          $t_mantis_bugnote_text_table        = config_get( 'mantis_bugnote_text_table' );
 493          $t_mantis_bug_monitor_table            = config_get( 'mantis_bug_monitor_table' );
 494          $t_mantis_bug_history_table            = config_get( 'mantis_bug_history_table' );
 495          $t_mantis_db = $g_db;
 496  
 497          $t_bug_id = db_prepare_int( $p_bug_id );
 498          $t_target_project_id = db_prepare_int( $p_target_project_id );
 499  
 500  
 501          $t_bug_data = new BugData;
 502          $t_bug_data = bug_get( $t_bug_id, true );
 503  
 504          # retrieve the project id associated with the bug
 505          if ( ( $p_target_project_id == null ) || is_blank( $p_target_project_id ) ) {
 506              $t_target_project_id = $t_bug_data->project_id;
 507          }
 508  
 509          $t_bug_data->project_id = $t_target_project_id;
 510  
 511          $t_new_bug_id = bug_create( $t_bug_data );
 512  
 513          # MASC ATTENTION: IF THE SOURCE BUG HAS TO HANDLER THE bug_create FUNCTION CAN TRY TO AUTO-ASSIGN THE BUG
 514          # WE FORCE HERE TO DUPLICATE THE SAME HANDLER OF THE SOURCE BUG
 515          # @@@ VB: Shouldn't we check if the handler in the source project is also a handler in the destination project?
 516          bug_set_field( $t_new_bug_id, 'handler_id', $t_bug_data->handler_id );
 517  
 518          bug_set_field( $t_new_bug_id, 'duplicate_id', $t_bug_data->duplicate_id );
 519          bug_set_field( $t_new_bug_id, 'status', $t_bug_data->status );
 520          bug_set_field( $t_new_bug_id, 'resolution', $t_bug_data->resolution );
 521          bug_set_field( $t_new_bug_id, 'projection', $t_bug_data->projection );
 522          bug_set_field( $t_new_bug_id, 'date_submitted', $t_mantis_db->DBTimeStamp( $t_bug_data->date_submitted ), false );
 523          bug_set_field( $t_new_bug_id, 'last_updated', $t_mantis_db->DBTimeStamp( $t_bug_data->last_updated ), false );
 524          bug_set_field( $t_new_bug_id, 'eta', $t_bug_data->eta );
 525          bug_set_field( $t_new_bug_id, 'fixed_in_version', $t_bug_data->fixed_in_version );
 526          bug_set_field( $t_new_bug_id, 'target_version', $t_bug_data->target_version );
 527          bug_set_field( $t_new_bug_id, 'sponsorship_total', 0 );
 528          bug_set_field( $t_new_bug_id, 'sticky', 0 );
 529  
 530          # COPY CUSTOM FIELDS
 531          if ( $p_copy_custom_fields ) {
 532              $query = "SELECT field_id, bug_id, value
 533                         FROM $t_mantis_custom_field_string_table
 534                         WHERE bug_id = '$t_bug_id';";
 535              $result = db_query( $query );
 536              $t_count = db_num_rows( $result );
 537  
 538              for ( $i = 0 ; $i < $t_count ; $i++ ) {
 539                  $t_bug_custom = db_fetch_array( $result );
 540  
 541                  $c_field_id = db_prepare_int( $t_bug_custom['field_id'] );
 542                  $c_new_bug_id = db_prepare_int( $t_new_bug_id );
 543                  $c_value = db_prepare_string( $t_bug_custom['value'] );
 544  
 545                  $query = "INSERT INTO $t_mantis_custom_field_string_table
 546                             ( field_id, bug_id, value )
 547                             VALUES ('$c_field_id', '$c_new_bug_id', '$c_value')";
 548                  db_query( $query );
 549              }
 550          }
 551  
 552          # COPY RELATIONSHIPS
 553          if ( $p_copy_relationships ) {
 554              if ( ON == config_get( 'enable_relationship' ) ) {
 555                  relationship_copy_all( $t_bug_id,$t_new_bug_id );
 556              }
 557          }
 558  
 559          # Copy bugnotes
 560          if ( $p_copy_bugnotes ) {
 561              $query = "SELECT *
 562                        FROM $t_mantis_bugnote_table
 563                        WHERE bug_id = '$t_bug_id';";
 564              $result = db_query( $query );
 565              $t_count = db_num_rows( $result );
 566  
 567              for ( $i = 0; $i < $t_count; $i++ ) {
 568                  $t_bug_note = db_fetch_array( $result );
 569                  $t_bugnote_text_id = $t_bug_note['bugnote_text_id'];
 570  
 571                  $query2 = "SELECT *
 572                             FROM $t_mantis_bugnote_text_table
 573                             WHERE id = '$t_bugnote_text_id';";
 574                  $result2 = db_query( $query2 );
 575                  $t_count2 = db_num_rows( $result2 );
 576  
 577                  $t_bugnote_text_insert_id = -1;
 578                  if ( $t_count2 > 0 ) {
 579                      $t_bugnote_text = db_fetch_array( $result2 );
 580                      $t_bugnote_text['note'] = db_prepare_string( $t_bugnote_text['note'] );
 581  
 582                      $query2 = "INSERT INTO $t_mantis_bugnote_text_table
 583                                 ( note )
 584                                 VALUES ( '" . $t_bugnote_text['note'] . "' );";
 585                      db_query( $query2 );
 586                      $t_bugnote_text_insert_id = db_insert_id( $t_mantis_bugnote_text_table );
 587                  }
 588  
 589                  $query2 = "INSERT INTO $t_mantis_bugnote_table
 590                             ( bug_id, reporter_id, bugnote_text_id, view_state, date_submitted, last_modified )
 591                             VALUES ( '$t_new_bug_id',
 592                                         '" . $t_bug_note['reporter_id'] . "',
 593                                         '$t_bugnote_text_insert_id',
 594                                         '" . $t_bug_note['view_state'] . "',
 595                                         '" . $t_bug_note['date_submitted'] . "',
 596                                         '" . $t_bug_note['last_modified'] . "' );";
 597                  db_query( $query2 );
 598              }
 599          }
 600  
 601          # Copy attachments
 602          if ( $p_copy_attachments ) {
 603              $query = "SELECT *
 604                        FROM $t_mantis_bug_file_table
 605                        WHERE bug_id = '$t_bug_id';";
 606              $result = db_query( $query );
 607              $t_count = db_num_rows( $result );
 608  
 609              $t_bug_file = array();
 610              for ( $i = 0; $i < $t_count; $i++ ) {
 611                  $t_bug_file = db_fetch_array( $result );
 612  
 613                  # prepare the new diskfile name and then copy the file
 614                  $t_file_path = dirname( $t_bug_file['folder'] );
 615                  $t_new_diskfile_name = $t_file_path . file_generate_unique_name( 'bug-' . $p_file_name, $t_file_path );
 616                  $t_new_file_name = file_get_display_name( $t_bug_file['filename'] );
 617                  if ( ( config_get( 'file_upload_method' ) == DISK ) ) {
 618                      copy( $t_bug_file['diskfile'], $t_new_diskfile_name );
 619                      chmod( $t_new_diskfile_name, config_get( 'attachments_file_permissions' ) );
 620                  }
 621  
 622                  $query = "INSERT INTO $t_mantis_bug_file_table
 623                          ( bug_id, title, description, diskfile, filename, folder, filesize, file_type, date_added, content )
 624                          VALUES ( '$t_new_bug_id',
 625                                   '" . db_prepare_string( $t_bug_file['title'] ) . "',
 626                                   '" . db_prepare_string( $t_bug_file['description'] ) . "',
 627                                   '" . db_prepare_string( $t_new_diskfile_name ) . "',
 628                                   '" . db_prepare_string( $t_new_file_name ) . "',
 629                                   '" . db_prepare_string( $t_bug_file['folder'] ) . "',
 630                                   '" . db_prepare_int( $t_bug_file['filesize'] ) . "',
 631                                   '" . db_prepare_string( $t_bug_file['file_type'] ) . "',
 632                                   '" . db_prepare_string( $t_bug_file['date_added'] ) . "',
 633                                   '" . db_prepare_string( $t_bug_file['content'] ) . "');";
 634                  db_query( $query );
 635              }
 636          }
 637  
 638          # Copy users monitoring bug
 639          if ( $p_copy_monitoring_users ) {
 640              $query = "SELECT *
 641                        FROM $t_mantis_bug_monitor_table
 642                        WHERE bug_id = '$t_bug_id';";
 643              $result = db_query( $query );
 644              $t_count = db_num_rows( $result );
 645  
 646              for ( $i = 0; $i < $t_count; $i++ ) {
 647                  $t_bug_monitor = db_fetch_array( $result );
 648                  $query = "INSERT INTO $t_mantis_bug_monitor_table
 649                           ( user_id, bug_id )
 650                           VALUES ( '" . $t_bug_monitor['user_id'] . "', '$t_new_bug_id' );";
 651                  db_query( $query );
 652              }
 653          }
 654  
 655          # COPY HISTORY
 656          history_delete( $t_new_bug_id );    # should history only be deleted inside the if statement below?
 657          if ( $p_copy_history ) {
 658              $query = "SELECT *
 659                        FROM $t_mantis_bug_history_table
 660                        WHERE bug_id = '$t_bug_id';";
 661              $result = db_query( $query );
 662              $t_count = db_num_rows( $result );
 663  
 664              for ( $i = 0; $i < $t_count; $i++ ) {
 665                  $t_bug_history = db_fetch_array( $result );
 666                  $query = "INSERT INTO $t_mantis_bug_history_table
 667                            ( user_id, bug_id, date_modified, field_name, old_value, new_value, type )
 668                            VALUES ( '" . db_prepare_int( $t_bug_history['user_id'] ) . "',
 669                                       '$t_new_bug_id',
 670                                       '" . db_prepare_string( $t_bug_history['date_modified'] ) . "',
 671                                       '" . db_prepare_string( $t_bug_history['field_name'] ) . "',
 672                                       '" . db_prepare_string( $t_bug_history['old_value'] ) . "',
 673                                       '" . db_prepare_string( $t_bug_history['new_value'] ) . "',
 674                                       '" . db_prepare_int( $t_bug_history['type'] ) . "' );";
 675                  db_query( $query );
 676              }
 677          }
 678  
 679          return $t_new_bug_id;
 680      }
 681  
 682      # --------------------
 683      # allows bug deletion :
 684      # delete the bug, bugtext, bugnote, and bugtexts selected
 685      # used in bug_delete.php & mass treatments
 686  	function bug_delete( $p_bug_id ) {
 687          $c_bug_id            = db_prepare_int( $p_bug_id );
 688          $t_bug_table        = config_get( 'mantis_bug_table' );
 689          $t_bug_text_table    = config_get( 'mantis_bug_text_table' );
 690  
 691          # call pre-deletion custom function
 692          helper_call_custom_function( 'issue_delete_validate', array( $p_bug_id ) );
 693  
 694          # log deletion of bug
 695          history_log_event_special( $p_bug_id, BUG_DELETED, bug_format_id( $p_bug_id ) );
 696  
 697          email_bug_deleted( $p_bug_id );
 698  
 699          # call post-deletion custom function.  We call this here to allow the custom function to access the details of the bug before 
 700          # they are deleted from the database given it's id.  The other option would be to move this to the end of the function and
 701          # provide it with bug data rather than an id, but this will break backward compatibility.
 702          helper_call_custom_function( 'issue_delete_notify', array( $p_bug_id ) );
 703  
 704          # Unmonitor bug for all users
 705          bug_unmonitor( $p_bug_id, null );
 706  
 707          # Delete custom fields
 708          custom_field_delete_all_values( $p_bug_id );
 709  
 710          # Delete bugnotes
 711          bugnote_delete_all( $p_bug_id );
 712  
 713          # Delete all sponsorships
 714          sponsorship_delete( sponsorship_get_all_ids( $p_bug_id ) );
 715  
 716          # MASC RELATIONSHIP
 717          # we delete relationships even if the feature is currently off.
 718          relationship_delete_all( $p_bug_id );
 719          # MASC RELATIONSHIP
 720  
 721          # Delete files
 722          file_delete_attachments( $p_bug_id );
 723  
 724          # Detach tags
 725          tag_bug_detach_all( $p_bug_id, false );
 726          
 727          # Delete the bug history
 728          history_delete( $p_bug_id );
 729  
 730          # Delete the bugnote text
 731          $t_bug_text_id = bug_get_field( $p_bug_id, 'bug_text_id' );
 732  
 733          $query = "DELETE FROM $t_bug_text_table
 734                    WHERE id='$t_bug_text_id'";
 735          db_query( $query );
 736  
 737          # Delete the bug entry
 738          $query = "DELETE FROM $t_bug_table
 739                    WHERE id='$c_bug_id'";
 740          db_query( $query );
 741  
 742          bug_clear_cache( $p_bug_id );
 743          bug_text_clear_cache( $p_bug_id );
 744  
 745          # db_query() errors on failure so:
 746          return true;
 747      }
 748  
 749      # --------------------
 750      # Delete all bugs associated with a project
 751  	function bug_delete_all( $p_project_id ) {
 752          $c_project_id = db_prepare_int( $p_project_id );
 753  
 754          $t_bug_table = config_get( 'mantis_bug_table' );
 755  
 756          $query = "SELECT id
 757                    FROM $t_bug_table
 758                    WHERE project_id='$c_project_id'";
 759          $result = db_query( $query );
 760  
 761          $bug_count = db_num_rows( $result );
 762  
 763          for ( $i=0 ; $i < $bug_count ; $i++ ) {
 764              $row = db_fetch_array( $result );
 765  
 766              bug_delete( $row['id'] );
 767          }
 768  
 769          # @@@ should we check the return value of each bug_delete() and
 770          #  return false if any of them return false? Presumable bug_delete()
 771          #  will eventually trigger an error on failure so it won't matter...
 772  
 773          return true;
 774      }
 775  
 776      # --------------------
 777      # Update a bug from the given data structure
 778      #  If the third parameter is true, also update the longer strings table
 779  	function bug_update( $p_bug_id, $p_bug_data, $p_update_extended = false, $p_bypass_mail = false ) {
 780          $c_bug_id        = db_prepare_int( $p_bug_id );
 781          $c_bug_data        = bug_prepare_db( $p_bug_data );
 782  
 783          # Summary cannot be blank
 784          if ( is_blank( $c_bug_data->summary ) ) {
 785              error_parameters( lang_get( 'summary' ) );
 786              trigger_error( ERROR_EMPTY_FIELD, ERROR );
 787          }
 788  
 789          if ( $p_update_extended ) {
 790              # Description field cannot be empty
 791              if ( is_blank( $c_bug_data->description ) ) {
 792                  error_parameters( lang_get( 'description' ) );
 793                  trigger_error( ERROR_EMPTY_FIELD, ERROR );
 794              }
 795          }
 796  
 797          if( !is_blank( $p_bug_data->duplicate_id ) && ( $p_bug_data->duplicate_id != 0 ) && ( $p_bug_id == $p_bug_data->duplicate_id ) ) {
 798              trigger_error( ERROR_BUG_DUPLICATE_SELF, ERROR );  # never returns
 799          }
 800  
 801          $t_old_data = bug_get( $p_bug_id, true );
 802  
 803          $t_bug_table = config_get( 'mantis_bug_table' );
 804  
 805          # Update all fields
 806          # Ignore date_submitted and last_updated since they are pulled out
 807          #  as unix timestamps which could confuse the history log and they
 808          #  shouldn't get updated like this anyway.  If you really need to change
 809          #  them use bug_set_field()
 810          $query = "UPDATE $t_bug_table
 811                  SET project_id='$c_bug_data->project_id',
 812                      reporter_id='$c_bug_data->reporter_id',
 813                      handler_id='$c_bug_data->handler_id',
 814                      duplicate_id='$c_bug_data->duplicate_id',
 815                      priority='$c_bug_data->priority',
 816                      severity='$c_bug_data->severity',
 817                      reproducibility='$c_bug_data->reproducibility',
 818                      status='$c_bug_data->status',
 819                      resolution='$c_bug_data->resolution',
 820                      projection='$c_bug_data->projection',
 821                      category='$c_bug_data->category',
 822                      eta='$c_bug_data->eta',
 823                      os='$c_bug_data->os',
 824                      os_build='$c_bug_data->os_build',
 825                      platform='$c_bug_data->platform',
 826                      version='$c_bug_data->version',
 827                      build='$c_bug_data->build',
 828                      fixed_in_version='$c_bug_data->fixed_in_version',";
 829  
 830          $t_roadmap_updated = false;
 831          if ( access_has_project_level( config_get( 'roadmap_update_threshold' ) ) ) {
 832              $query .= "
 833                      target_version='$c_bug_data->target_version',";
 834              $t_roadmap_updated = true;
 835          }
 836  
 837          $query .= "
 838                      view_state='$c_bug_data->view_state',
 839                      summary='$c_bug_data->summary',
 840                      sponsorship_total='$c_bug_data->sponsorship_total',
 841                      sticky='$c_bug_data->sticky'
 842                  WHERE id='$c_bug_id'";
 843          db_query( $query );
 844  
 845          bug_clear_cache( $p_bug_id );
 846  
 847          # log changes
 848          history_log_event_direct( $p_bug_id, 'project_id', $t_old_data->project_id, $p_bug_data->project_id );
 849          history_log_event_direct( $p_bug_id, 'reporter_id', $t_old_data->reporter_id, $p_bug_data->reporter_id );
 850          history_log_event_direct( $p_bug_id, 'handler_id', $t_old_data->handler_id, $p_bug_data->handler_id );
 851          history_log_event_direct( $p_bug_id, 'duplicate_id', $t_old_data->duplicate_id, $p_bug_data->duplicate_id );
 852          history_log_event_direct( $p_bug_id, 'priority', $t_old_data->priority, $p_bug_data->priority );
 853          history_log_event_direct( $p_bug_id, 'severity', $t_old_data->severity, $p_bug_data->severity );
 854          history_log_event_direct( $p_bug_id, 'reproducibility', $t_old_data->reproducibility, $p_bug_data->reproducibility );
 855          history_log_event_direct( $p_bug_id, 'status', $t_old_data->status, $p_bug_data->status );
 856          history_log_event_direct( $p_bug_id, 'resolution', $t_old_data->resolution, $p_bug_data->resolution );
 857          history_log_event_direct( $p_bug_id, 'projection', $t_old_data->projection, $p_bug_data->projection );
 858          history_log_event_direct( $p_bug_id, 'category', $t_old_data->category, $p_bug_data->category );
 859          history_log_event_direct( $p_bug_id, 'eta',    $t_old_data->eta, $p_bug_data->eta );
 860          history_log_event_direct( $p_bug_id, 'os', $t_old_data->os, $p_bug_data->os );
 861          history_log_event_direct( $p_bug_id, 'os_build', $t_old_data->os_build, $p_bug_data->os_build );
 862          history_log_event_direct( $p_bug_id, 'platform', $t_old_data->platform, $p_bug_data->platform );
 863          history_log_event_direct( $p_bug_id, 'version', $t_old_data->version, $p_bug_data->version );
 864          history_log_event_direct( $p_bug_id, 'build', $t_old_data->build, $p_bug_data->build );
 865          history_log_event_direct( $p_bug_id, 'fixed_in_version', $t_old_data->fixed_in_version, $p_bug_data->fixed_in_version );
 866          if ( $t_roadmap_updated ) {
 867              history_log_event_direct( $p_bug_id, 'target_version', $t_old_data->target_version, $p_bug_data->target_version );
 868          }
 869          history_log_event_direct( $p_bug_id, 'view_state', $t_old_data->view_state, $p_bug_data->view_state );
 870          history_log_event_direct( $p_bug_id, 'summary', $t_old_data->summary, $p_bug_data->summary );
 871          history_log_event_direct( $p_bug_id, 'sponsorship_total', $t_old_data->sponsorship_total, $p_bug_data->sponsorship_total );
 872          history_log_event_direct( $p_bug_id, 'sticky', $t_old_data->sticky, $p_bug_data->sticky );
 873  
 874          # Update extended info if requested
 875          if ( $p_update_extended ) {
 876              $t_bug_text_table = config_get( 'mantis_bug_text_table' );
 877  
 878              $t_bug_text_id = bug_get_field( $p_bug_id, 'bug_text_id' );
 879  
 880              $query = "UPDATE $t_bug_text_table
 881                          SET description='$c_bug_data->description',
 882                              steps_to_reproduce='$c_bug_data->steps_to_reproduce',
 883                              additional_information='$c_bug_data->additional_information'
 884                          WHERE id='$t_bug_text_id'";
 885              db_query( $query );
 886  
 887              bug_text_clear_cache( $p_bug_id );
 888  
 889              if ( $t_old_data->description != $p_bug_data->description ) {
 890                  history_log_event_special( $p_bug_id, DESCRIPTION_UPDATED );
 891              }
 892              if ( $t_old_data->steps_to_reproduce != $p_bug_data->steps_to_reproduce ) {
 893                  history_log_event_special( $p_bug_id, STEP_TO_REPRODUCE_UPDATED );
 894              }
 895              if ( $t_old_data->additional_information != $p_bug_data->additional_information ) {
 896                  history_log_event_special( $p_bug_id, ADDITIONAL_INFO_UPDATED );
 897              }
 898          }
 899  
 900          # Update the last update date
 901          bug_update_date( $p_bug_id );
 902  
 903          if ( false == $p_bypass_mail ) {        # allow bypass if user is sending mail separately
 904              $t_action_prefix = 'email_notification_title_for_action_bug_';
 905              $t_status_prefix = 'email_notification_title_for_status_bug_';
 906  
 907              # status changed
 908              if ( $t_old_data->status != $p_bug_data->status ) {
 909                  $t_status = get_enum_to_string( config_get( 'status_enum_string' ), $p_bug_data->status );
 910                  $t_status = str_replace( ' ', '_', $t_status );
 911                  email_generic( $p_bug_id, $t_status, $t_status_prefix . $t_status );
 912                  return true;
 913              }
 914  
 915              # bug assigned
 916              if ( $t_old_data->handler_id != $p_bug_data->handler_id ) {
 917                  email_generic( $p_bug_id, 'owner', $t_action_prefix . 'assigned' );
 918                  return true;
 919              }
 920  
 921              # @@@ handle priority change if it requires special handling
 922  
 923              # generic update notification
 924              email_generic( $p_bug_id, 'updated', $t_action_prefix . 'updated' );
 925          }
 926  
 927          return true;
 928      }
 929  
 930      #===================================
 931      # Data Access
 932      #===================================
 933  
 934      # --------------------
 935      # Returns the extended record of the specified bug, this includes
 936      # the bug text fields
 937      # @@@ include reporter name and handler name, the problem is that
 938      #      handler can be 0, in this case no corresponding name will be
 939      #      found.  Use equivalent of (+) in Oracle.
 940  	function bug_get_extended_row( $p_bug_id ) {
 941          $t_base = bug_cache_row( $p_bug_id );
 942          $t_text = bug_text_cache_row( $p_bug_id );
 943  
 944          # merge $t_text first so that the 'id' key has the bug id not the bug text id
 945          return array_merge( $t_text, $t_base );
 946      }
 947  
 948      # --------------------
 949      # Returns the record of the specified bug
 950  	function bug_get_row( $p_bug_id ) {
 951          return bug_cache_row( $p_bug_id );
 952      }
 953  
 954      # --------------------
 955      # Returns an object representing the specified bug
 956  	function bug_get( $p_bug_id, $p_get_extended = false ) {
 957          if ( $p_get_extended ) {
 958              $row = bug_get_extended_row( $p_bug_id );
 959          } else {
 960              $row = bug_get_row( $p_bug_id );
 961          }
 962  
 963          $t_bug_data = new BugData;
 964          $t_row_keys = array_keys( $row );
 965          $t_vars = get_object_vars( $t_bug_data );
 966  
 967          # Check each variable in the class
 968          foreach ( $t_vars as $var => $val ) {
 969              # If we got a field from the DB with the same name
 970              if ( in_array( $var, $t_row_keys, true ) ) {
 971                  # Store that value in the object
 972                  $t_bug_data->$var = $row[$var];
 973              }
 974          }
 975  
 976          return $t_bug_data;
 977      }
 978  
 979      # --------------------
 980      # return the specified field of the given bug
 981      #  if the field does not exist, display a warning and return ''
 982  	function bug_get_field( $p_bug_id, $p_field_name ) {
 983          $row = bug_get_row( $p_bug_id );
 984  
 985          if ( isset( $row[$p_field_name] ) ) {
 986              return $row[$p_field_name];
 987          } else {
 988              error_parameters( $p_field_name );
 989              trigger_error( ERROR_DB_FIELD_NOT_FOUND, WARNING );
 990              return '';
 991          }
 992      }
 993  
 994      # --------------------
 995      # return the specified text field of the given bug
 996      #  if the field does not exist, display a warning and return ''
 997  	function bug_get_text_field( $p_bug_id, $p_field_name ) {
 998          $row = bug_text_cache_row( $p_bug_id );
 999  
1000          if ( isset( $row[$p_field_name] ) ) {
1001              return $row[$p_field_name];
1002          } else {
1003              error_parameters( $p_field_name );
1004              trigger_error( ERROR_DB_FIELD_NOT_FOUND, WARNING );
1005              return '';
1006          }
1007      }
1008  
1009      # --------------------
1010      # return the bug summary
1011      #  this is a wrapper for the custom function
1012  	function bug_format_summary( $p_bug_id, $p_context ) {
1013          return     helper_call_custom_function( 'format_issue_summary', array( $p_bug_id , $p_context ) );
1014      }
1015  
1016  
1017      # --------------------
1018      # Returns the number of bugnotes for the given bug_id
1019  	function bug_get_bugnote_count( $p_bug_id ) {
1020          $c_bug_id = db_prepare_int( $p_bug_id );
1021  
1022          $t_project_id = bug_get_field( $p_bug_id, 'project_id' );
1023  
1024          if ( !access_has_project_level( config_get( 'private_bugnote_threshold' ), $t_project_id ) ) {
1025              $t_restriction = 'AND view_state=' . VS_PUBLIC;
1026          } else {
1027              $t_restriction = '';
1028          }
1029  
1030          $t_bugnote_table = config_get( 'mantis_bugnote_table' );
1031          $query = "SELECT COUNT(*)
1032                    FROM $t_bugnote_table
1033                    WHERE bug_id ='$c_bug_id' $t_restriction";
1034          $result = db_query( $query );
1035  
1036          return db_result( $result );
1037      }
1038  
1039      # --------------------
1040      # return the timestamp for the most recent time at which a bugnote
1041      #  associated wiht the bug was modified
1042  	function bug_get_newest_bugnote_timestamp( $p_bug_id ) {
1043          $c_bug_id            = db_prepare_int( $p_bug_id );
1044          $t_bugnote_table    = config_get( 'mantis_bugnote_table' );
1045  
1046          $query = "SELECT last_modified
1047                    FROM $t_bugnote_table
1048                    WHERE bug_id='$c_bug_id'
1049                    ORDER BY last_modified DESC";
1050          $result = db_query( $query, 1 );
1051          $row = db_result( $result );
1052  
1053          if ( false === $row ) {
1054              return false;
1055          } else {
1056              return db_unixtimestamp( $row );
1057          }
1058      }
1059  
1060      # --------------------
1061      # return the timestamp for the most recent time at which a bugnote
1062      #  associated with the bug was modified and the total bugnote
1063      #  count in one db query
1064  	function bug_get_bugnote_stats( $p_bug_id ) {
1065          global $g_cache_bug;
1066          $c_bug_id            = db_prepare_int( $p_bug_id );
1067  
1068          if( !is_null( $g_cache_bug[ $c_bug_id ]['_stats'] ) ) {
1069              if( $g_cache_bug[ $c_bug_id ]['_stats'] === false ) { 
1070                  return false;            
1071              } else {
1072                  $t_stats['last_modified'] = db_unixtimestamp( $g_cache_bug[ $c_bug_id ]['_stats']['last_modified'] );
1073                  $t_stats['count'] = $g_cache_bug[ $c_bug_id ]['_stats']['count'];
1074              }
1075              return $t_stats;
1076          }
1077  
1078          $t_bugnote_table    = config_get( 'mantis_bugnote_table' );
1079  
1080          $query = "SELECT last_modified
1081                    FROM $t_bugnote_table
1082                    WHERE bug_id='$c_bug_id'
1083                    ORDER BY last_modified DESC";
1084          $result = db_query( $query );
1085          $row = db_fetch_array( $result );
1086  
1087          if ( false === $row )
1088              return false;
1089  
1090          $t_stats['last_modified'] = db_unixtimestamp( $row['last_modified'] );
1091          $t_stats['count'] = db_num_rows( $result );
1092  
1093          return $t_stats;
1094      }
1095  
1096      # --------------------
1097      # Get array of attachments associated with the specified bug id.  The array will be
1098      # sorted in terms of date added (ASC).  The array will include the following fields:
1099      # id, title, diskfile, filename, filesize, file_type, date_added.
1100  	function bug_get_attachments( $p_bug_id ) {
1101          if ( !file_can_view_bug_attachments( $p_bug_id ) ) {
1102              return;
1103          }
1104  
1105          $c_bug_id = db_prepare_int( $p_bug_id );
1106  
1107          $t_bug_file_table = config_get( 'mantis_bug_file_table' );
1108  
1109          $query = "SELECT id, title, diskfile, filename, filesize, file_type, date_added
1110                          FROM $t_bug_file_table
1111                          WHERE bug_id='$c_bug_id'
1112                          ORDER BY date_added";
1113          $db_result = db_query( $query );
1114          $num_notes = db_num_rows( $db_result );
1115  
1116          $t_result = array();
1117  
1118          for ( $i = 0; $i < $num_notes; $i++ ) {
1119              $t_result[] = db_fetch_array( $db_result );
1120          }
1121  
1122          return $t_result;
1123      }
1124  
1125      #===================================
1126      # Data Modification
1127      #===================================
1128  
1129      # --------------------
1130      # set the value of a bug field
1131  	function bug_set_field( $p_bug_id, $p_field_name, $p_status, $p_prepare = true ) {
1132          $c_bug_id            = db_prepare_int( $p_bug_id );
1133          $c_field_name        = db_prepare_string( $p_field_name );
1134          if( $p_prepare ) {
1135              $c_status        = '\'' . db_prepare_string( $p_status ) . '\''; #generic, unknown type
1136          } else {
1137              $c_status        =  $p_status; #generic, unknown type
1138          }
1139  
1140          $h_status = bug_get_field( $p_bug_id, $p_field_name );
1141  
1142          # return if status is already set
1143          if ( $c_status == $h_status ) {
1144              return true;
1145          }
1146  
1147          $t_bug_table = config_get( 'mantis_bug_table' );
1148  
1149          # Update fields
1150          $query = "UPDATE $t_bug_table
1151                    SET $c_field_name=$c_status
1152                    WHERE id='$c_bug_id'";
1153          db_query( $query );
1154  
1155          # updated the last_updated date
1156          bug_update_date( $p_bug_id );
1157  
1158          # log changes
1159          history_log_event_direct( $p_bug_id, $p_field_name, $h_status, $p_status );
1160  
1161          bug_clear_cache( $p_bug_id );
1162  
1163          return true;
1164      }
1165  
1166      # --------------------
1167      # assign the bug to the given user
1168  	function bug_assign( $p_bug_id, $p_user_id, $p_bugnote_text='', $p_bugnote_private = false ) {
1169          $c_bug_id    = db_prepare_int( $p_bug_id );
1170          $c_user_id    = db_prepare_int( $p_user_id );
1171  
1172          if ( ( $c_user_id != NO_USER ) && !access_has_bug_level( config_get( 'handle_bug_threshold' ), $p_bug_id, $p_user_id ) ) {
1173              trigger_error( ERROR_USER_DOES_NOT_HAVE_REQ_ACCESS );
1174          }
1175  
1176          # extract current information into history variables
1177          $h_status        = bug_get_field( $p_bug_id, 'status' );
1178          $h_handler_id    = bug_get_field( $p_bug_id, 'handler_id' );
1179  
1180          if ( ( ON == config_get( 'auto_set_status_to_assigned' ) ) &&
1181               ( NO_USER != $p_user_id ) ) {
1182              $t_ass_val = config_get( 'bug_assigned_status' );
1183          } else {
1184              $t_ass_val = $h_status;
1185          }
1186  
1187          $t_bug_table = config_get( 'mantis_bug_table' );
1188  
1189          if ( ( $t_ass_val != $h_status ) || ( $p_user_id != $h_handler_id ) ) {
1190  
1191              # get user id
1192              $query = "UPDATE $t_bug_table
1193                        SET handler_id='$c_user_id', status='$t_ass_val'
1194                        WHERE id='$c_bug_id'";
1195              db_query( $query );
1196  
1197              # log changes
1198              history_log_event_direct( $c_bug_id, 'status', $h_status, $t_ass_val );
1199              history_log_event_direct( $c_bug_id, 'handler_id', $h_handler_id, $p_user_id );
1200  
1201              # Add bugnote if supplied
1202              if ( !is_blank( $p_bugnote_text ) ) {
1203                  bugnote_add( $p_bug_id, $p_bugnote_text, 0, $p_bugnote_private );
1204              }
1205  
1206              # updated the last_updated date
1207              bug_update_date( $p_bug_id );
1208  
1209              bug_clear_cache( $p_bug_id );
1210  
1211              # send assigned to email
1212              email_assign( $p_bug_id );
1213          }
1214  
1215          return true;
1216      }
1217  
1218      # --------------------
1219      # close the given bug
1220  	function bug_close( $p_bug_id, $p_bugnote_text = '', $p_bugnote_private = false, $p_time_tracking = '0:00' ) {
1221          $p_bugnote_text = trim( $p_bugnote_text );
1222  
1223          bug_set_field( $p_bug_id, 'status', CLOSED );
1224  
1225          # Add bugnote if supplied
1226          if ( !is_blank( $p_bugnote_text ) ) {
1227              bugnote_add( $p_bug_id, $p_bugnote_text, $p_time_tracking, $p_bugnote_private );
1228          }
1229  
1230          email_close( $p_bug_id );
1231  
1232          # MASC RELATIONSHIP
1233          if ( ON == config_get( 'enable_relationship' ) ) {
1234              email_relationship_child_closed( $p_bug_id );
1235          }
1236          # MASC RELATIONSHIP
1237  
1238          return true;
1239      }
1240  
1241      # --------------------
1242      # resolve the given bug
1243  	function bug_resolve( $p_bug_id, $p_resolution, $p_fixed_in_version = '', $p_bugnote_text = '', $p_duplicate_id = null, $p_handler_id = null, $p_bugnote_private = false, $p_time_tracking = '0:00' ) {
1244          $p_bugnote_text = trim( $p_bugnote_text );
1245  
1246          $t_duplicate = !is_blank( $p_duplicate_id ) && ( $p_duplicate_id != 0 );
1247          if ( $t_duplicate ) {
1248              if ( $p_bug_id == $p_duplicate_id ) {
1249                  trigger_error( ERROR_BUG_DUPLICATE_SELF, ERROR );  # never returns
1250              }
1251  
1252              # the related bug exists...
1253              bug_ensure_exists( $p_duplicate_id );
1254  
1255              if ( ON == config_get( 'enable_relationship' ) ) {
1256                  # check if there is other relationship between the bugs...
1257                  $t_id_relationship = relationship_same_type_exists( $p_bug_id, $p_duplicate_id, BUG_DUPLICATE );
1258  
1259                  if ( $t_id_relationship == -1 ) {
1260                      # the relationship type is already set. Nothing to do
1261                  }
1262                  else if ( $t_id_relationship > 0 ) {
1263                      # there is already a relationship between them -> we have to update it and not to add a new one
1264                      helper_ensure_confirmed( lang_get( 'replace_relationship_sure_msg' ), lang_get( 'replace_relationship_button' ) );
1265  
1266                      # Update the relationship
1267                      relationship_update( $t_id_relationship, $p_bug_id, $p_duplicate_id, BUG_DUPLICATE );
1268  
1269                      # Add log line to the history (both bugs)
1270                      history_log_event_special( $p_bug_id, BUG_REPLACE_RELATIONSHIP, BUG_DUPLICATE, $p_duplicate_id );
1271                      history_log_event_special( $p_duplicate_id, BUG_REPLACE_RELATIONSHIP, BUG_HAS_DUPLICATE, $p_bug_id );
1272                  }
1273                  else {
1274                      # Add the new relationship
1275                      relationship_add( $p_bug_id, $p_duplicate_id, BUG_DUPLICATE );
1276  
1277                      # Add log line to the history (both bugs)
1278                      history_log_event_special( $p_bug_id, BUG_ADD_RELATIONSHIP, BUG_DUPLICATE, $p_duplicate_id );
1279                      history_log_event_special( $p_duplicate_id, BUG_ADD_RELATIONSHIP, BUG_HAS_DUPLICATE, $p_bug_id );
1280                  }
1281              }
1282  
1283              bug_set_field( $p_bug_id, 'duplicate_id', (int)$p_duplicate_id );
1284          }
1285          
1286          $c_resolution = db_prepare_int( $p_resolution );
1287  
1288          bug_set_field( $p_bug_id, 'status', config_get( 'bug_resolved_status_threshold' ) );
1289          bug_set_field( $p_bug_id, 'fixed_in_version', $p_fixed_in_version );
1290          bug_set_field( $p_bug_id, 'resolution', $c_resolution );
1291  
1292          # only set handler if specified explicitly or if bug was not assigned to a handler
1293          if ( null == $p_handler_id ) {
1294              if ( bug_get_field( $p_bug_id, 'handler_id' ) == 0 ) {
1295                  $p_handler_id = auth_get_current_user_id();
1296                  bug_set_field( $p_bug_id, 'handler_id', $p_handler_id );
1297              }
1298          } else {
1299              bug_set_field( $p_bug_id, 'handler_id', $p_handler_id );
1300          }
1301  
1302          # Add bugnote if supplied
1303          if ( !is_blank( $p_bugnote_text ) ) {
1304              bugnote_add( $p_bug_id, $p_bugnote_text, $p_time_tracking, $p_bugnote_private );
1305          }
1306  
1307          email_resolved( $p_bug_id );
1308  
1309          if ( $c_resolution == FIXED ) {
1310              twitter_issue_resolved( $p_bug_id );
1311          }
1312  
1313          # MASC RELATIONSHIP
1314          if ( ON == config_get( 'enable_relationship' ) ) {
1315              email_relationship_child_resolved( $p_bug_id );
1316          }
1317          # MASC RELATIONSHIP
1318  
1319          return true;
1320      }
1321  
1322      # --------------------
1323      # reopen the given bug
1324  	function bug_reopen( $p_bug_id, $p_bugnote_text='', $p_time_tracking = '0:00', $p_bugnote_private = false ) {
1325          $p_bugnote_text = trim( $p_bugnote_text );
1326  
1327          bug_set_field( $p_bug_id, 'status', config_get( 'bug_reopen_status' ) );
1328          bug_set_field( $p_bug_id, 'resolution', config_get( 'bug_reopen_resolution' ) );
1329  
1330          # Add bugnote if supplied
1331          if ( !is_blank( $p_bugnote_text ) ) {
1332              bugnote_add( $p_bug_id, $p_bugnote_text, $p_time_tracking, $p_bugnote_private );
1333          }
1334  
1335          email_reopen( $p_bug_id );
1336  
1337          return true;
1338      }
1339  
1340      # --------------------
1341      # updates the last_updated field
1342  	function bug_update_date( $p_bug_id ) {
1343          $c_bug_id = db_prepare_int( $p_bug_id );
1344  
1345          $t_bug_table = config_get( 'mantis_bug_table' );
1346  
1347          $query = "UPDATE $t_bug_table
1348                    SET last_updated= " . db_now() . "
1349                    WHERE id='$c_bug_id'";
1350          db_query( $query );
1351  
1352          bug_clear_cache( $p_bug_id );
1353  
1354          return true;
1355      }
1356  
1357      # --------------------
1358      # enable monitoring of this bug for the user
1359  	function bug_monitor( $p_bug_id, $p_user_id ) {
1360          $c_bug_id    = db_prepare_int( $p_bug_id );
1361          $c_user_id    = db_prepare_int( $p_user_id );
1362  
1363          # Make sure we aren't already monitoring this bug
1364          if ( user_is_monitoring_bug( $p_user_id, $p_bug_id ) ) {
1365              return true;
1366          }
1367  
1368          $t_bug_monitor_table = config_get( 'mantis_bug_monitor_table' );
1369  
1370          # Insert monitoring record
1371          $query ="INSERT ".
1372                  "INTO $t_bug_monitor_table ".
1373                  "( user_id, bug_id ) ".
1374                  "VALUES ".
1375                  "( '$c_user_id', '$c_bug_id' )";
1376          db_query( $query );
1377  
1378          # log new monitoring action
1379          history_log_event_special( $p_bug_id, BUG_MONITOR, $c_user_id );
1380  
1381          return true;
1382      }
1383  
1384      # --------------------
1385      # disable monitoring of this bug for the user
1386      # if $p_user_id = null, then bug is unmonitored for all users.
1387  	function bug_unmonitor( $p_bug_id, $p_user_id ) {
1388          $c_bug_id    = db_prepare_int( $p_bug_id );
1389          $c_user_id    = db_prepare_int( $p_user_id );
1390  
1391          $t_bug_monitor_table = config_get( 'mantis_bug_monitor_table' );
1392  
1393          # Delete monitoring record
1394          $query ="DELETE ".
1395                  "FROM $t_bug_monitor_table ".
1396                  "WHERE bug_id = '$c_bug_id'";
1397  
1398          if ( $p_user_id !== null ) {
1399              $query .= " AND user_id = '$c_user_id'";
1400          }
1401  
1402          db_query( $query );
1403  
1404          # log new un-monitor action
1405          history_log_event_special( $p_bug_id, BUG_UNMONITOR, $p_user_id );
1406  
1407          return true;
1408      }
1409  
1410      #===================================
1411      # Other
1412      #===================================
1413  
1414      # --------------------
1415      # Pads the bug id with the appropriate number of zeros.
1416  	function bug_format_id( $p_bug_id ) {
1417          $t_padding = config_get( 'display_bug_padding' );
1418          return( str_pad( $p_bug_id, $t_padding, '0', STR_PAD_LEFT ) );
1419      }
1420  
1421      # --------------------
1422      # Return a copy of the bug structure with all the instvars prepared for db insertion
1423  	function bug_prepare_db( $p_bug_data ) {
1424          $t_bug_data = new BugData;
1425          $t_bug_data->project_id            = db_prepare_int( $p_bug_data->project_id );
1426          $t_bug_data->reporter_id        = db_prepare_int( $p_bug_data->reporter_id );
1427          $t_bug_data->handler_id            = db_prepare_int( $p_bug_data->handler_id );
1428          $t_bug_data->duplicate_id        = db_prepare_int( $p_bug_data->duplicate_id );
1429          $t_bug_data->priority            = db_prepare_int( $p_bug_data->priority );
1430          $t_bug_data->severity            = db_prepare_int( $p_bug_data->severity );
1431          $t_bug_data->reproducibility    = db_prepare_int( $p_bug_data->reproducibility );
1432          $t_bug_data->status                = db_prepare_int( $p_bug_data->status );
1433          $t_bug_data->resolution            = db_prepare_int( $p_bug_data->resolution );
1434          $t_bug_data->projection            = db_prepare_int( $p_bug_data->projection );
1435          $t_bug_data->category            = db_prepare_string( $p_bug_data->category );
1436          $t_bug_data->date_submitted        = db_prepare_string( $p_bug_data->date_submitted );
1437          $t_bug_data->last_updated        = db_prepare_string( $p_bug_data->last_updated );
1438          $t_bug_data->eta                = db_prepare_int( $p_bug_data->eta );
1439          $t_bug_data->os                    = db_prepare_string( $p_bug_data->os );
1440          $t_bug_data->os_build            = db_prepare_string( $p_bug_data->os_build );
1441          $t_bug_data->platform            = db_prepare_string( $p_bug_data->platform );
1442          $t_bug_data->version            = db_prepare_string( $p_bug_data->version );
1443          $t_bug_data->build                = db_prepare_string( $p_bug_data->build );
1444          $t_bug_data->fixed_in_version    = db_prepare_string( $p_bug_data->fixed_in_version );
1445          $t_bug_data->target_version        = db_prepare_string( $p_bug_data->target_version );
1446          $t_bug_data->view_state            = db_prepare_int( $p_bug_data->view_state );
1447          $t_bug_data->summary            = db_prepare_string( $p_bug_data->summary );
1448          $t_bug_data->sponsorship_total    = db_prepare_int( $p_bug_data->sponsorship_total );
1449          $t_bug_data->sticky                = db_prepare_int( $p_bug_data->sticky );
1450  
1451          $t_bug_data->description        = db_prepare_string( $p_bug_data->description );
1452          $t_bug_data->steps_to_reproduce    = db_prepare_string( $p_bug_data->steps_to_reproduce );
1453          $t_bug_data->additional_information    = db_prepare_string( $p_bug_data->additional_information );
1454  
1455          return $t_bug_data;
1456      }
1457  
1458      # --------------------
1459      # Return a copy of the bug structure with all the instvars prepared for editing
1460      #  in an HTML form
1461  	function bug_prepare_edit( $p_bug_data ) {
1462          $p_bug_data->category            = string_attribute( $p_bug_data->category );
1463          $p_bug_data->date_submitted        = string_attribute( $p_bug_data->date_submitted );
1464          $p_bug_data->last_updated        = string_attribute( $p_bug_data->last_updated );
1465          $p_bug_data->os                    = string_attribute( $p_bug_data->os );
1466          $p_bug_data->os_build            = string_attribute( $p_bug_data->os_build );
1467          $p_bug_data->platform            = string_attribute( $p_bug_data->platform );
1468          $p_bug_data->version            = string_attribute( $p_bug_data->version );
1469          $p_bug_data->build                = string_attribute( $p_bug_data->build );
1470          $p_bug_data->fixed_in_version    = string_attribute( $p_bug_data->fixed_in_version );
1471          $p_bug_data->summary            = string_attribute( $p_bug_data->summary );
1472          $p_bug_data->sponsorship_total    = string_attribute( $p_bug_data->sponsorship_total );
1473          $p_bug_data->sticky                = string_attribute( $p_bug_data->sticky );
1474  
1475          $p_bug_data->description        = string_textarea( $p_bug_data->description );
1476          $p_bug_data->steps_to_reproduce    = string_textarea( $p_bug_data->steps_to_reproduce );
1477          $p_bug_data->additional_information    = string_textarea( $p_bug_data->additional_information );
1478  
1479          return $p_bug_data;
1480      }
1481  
1482      # --------------------
1483      # Return a copy of the bug structure with all the instvars prepared for editing
1484      #  in an HTML form
1485  	function bug_prepare_display( $p_bug_data ) {
1486          $p_bug_data->category            = string_display_line( $p_bug_data->category );
1487          $p_bug_data->date_submitted        = string_display_line( $p_bug_data->date_submitted );
1488          $p_bug_data->last_updated        = string_display_line( $p_bug_data->last_updated );
1489          $p_bug_data->os                    = string_display_line( $p_bug_data->os );
1490          $p_bug_data->os_build            = string_display_line( $p_bug_data->os_build );
1491          $p_bug_data->platform            = string_display_line( $p_bug_data->platform );
1492          $p_bug_data->version            = string_display_line( $p_bug_data->version );
1493          $p_bug_data->build                = string_display_line( $p_bug_data->build );
1494          $p_bug_data->fixed_in_version    = string_display_line( $p_bug_data->fixed_in_version );
1495          $p_bug_data->summary            = string_display_line_links( $p_bug_data->summary );
1496          $p_bug_data->sponsorship_total    = string_display_line( $p_bug_data->sponsorship_total );
1497          $p_bug_data->sticky                = string_display_line( $p_bug_data->sticky );
1498  
1499          $p_bug_data->description        = string_display_links( $p_bug_data->description );
1500          $p_bug_data->steps_to_reproduce    = string_display_links( $p_bug_data->steps_to_reproduce );
1501          $p_bug_data->additional_information    = string_display_links( $p_bug_data->additional_information );
1502  
1503          return $p_bug_data;
1504      }
1505  ?>


Généré le : Thu Nov 29 09:42:17 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics