[ Index ] |
|
Code source de Mantis 1.1.0rc3 |
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 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Thu Nov 29 09:42:17 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |