| [ Index ] |
|
Code source de Mantis 1.1.0rc3 |
1 <?php 2 # MantisConnect - A webservice interface to Mantis Bug Tracker 3 # Copyright (C) 2004-2007 Victor Boctor - vboctor@users.sourceforge.net 4 # This program is distributed under dual licensing. These include 5 # GPL and a commercial licenses. Victor Boctor reserves the right to 6 # change the license of future releases. 7 # See docs/ folder for more details 8 9 # -------------------------------------------------------- 10 # $Id: mc_issue_api.php,v 1.1 2007-07-18 06:52:55 vboctor Exp $ 11 # -------------------------------------------------------- 12 13 require_once( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'mc_core.php' ); 14 15 /** 16 * Check if an issue with the given id exists. 17 * 18 * @param string $p_username The name of the user trying to access the issue. 19 * @param string $p_password The password of the user. 20 * @param integer $p_issue_id The id of the issue to check. 21 * @return boolean true if there is an issue with the given id, false otherwise. 22 */ 23 function mc_issue_exists( $p_username, $p_password, $p_issue_id ) { 24 $t_user_id = mci_check_login( $p_username, $p_password ); 25 if ( $t_user_id === false ) { 26 return new soap_fault( 'Client', '', 'Access Denied' ); 27 } 28 29 if ( !bug_exists( $p_issue_id ) ) { 30 return false; 31 } 32 33 $t_project_id = bug_get_field( $p_issue_id, 'project_id' ); 34 if ( !mci_has_readonly_access( $t_user_id, $t_project_id ) ) { 35 // if we return an error here, then we answered the question! 36 return false; 37 } 38 39 return true; 40 } 41 42 /** 43 * Get all details about an issue. 44 * 45 * @param string $p_username The name of the user trying to access the issue. 46 * @param string $p_password The password of the user. 47 * @param integer $p_issue_id The id of the issue to retrieve. 48 * @return Array that represents an IssueData structure 49 */ 50 function mc_issue_get( $p_username, $p_password, $p_issue_id ) { 51 $t_user_id = mci_check_login( $p_username, $p_password ); 52 $t_lang = mci_get_user_lang( $t_user_id ); 53 if ( $t_user_id === false ) { 54 return new soap_fault( 'Client', '', 'Access Denied' ); 55 } 56 57 if ( !bug_exists( $p_issue_id ) ) { 58 return new soap_fault( 'Server', '', 'Issue does not exist' ); 59 } 60 61 $t_project_id = bug_get_field( $p_issue_id, 'project_id' ); 62 if ( !mci_has_readonly_access( $t_user_id, $t_project_id ) ) { 63 return new soap_fault( 'Client', '', 'Access Denied' ); 64 } 65 66 $t_bug = get_object_vars( bug_get( $p_issue_id, true ) ); 67 $t_issue_data = array(); 68 69 $t_issue_data['id'] = $p_issue_id; 70 $t_issue_data['view_state'] = mci_enum_get_array_by_id( $t_bug['view_state'], 'view_state', $t_lang ); 71 $t_issue_data['last_updated'] = timestamp_to_iso8601( $t_bug['last_updated'] ); 72 73 $t_issue_data['project'] = mci_project_as_array_by_id( $t_bug['project_id'] ); 74 $t_issue_data['category'] = mci_null_if_empty( $t_bug['category'] ); 75 $t_issue_data['priority'] = mci_enum_get_array_by_id( $t_bug['priority'], 'priority', $t_lang ); 76 $t_issue_data['severity'] = mci_enum_get_array_by_id( $t_bug['severity'], 'severity', $t_lang ); 77 $t_issue_data['status'] = mci_enum_get_array_by_id( $t_bug['status'], 'status', $t_lang ); 78 79 $t_issue_data['reporter'] = mci_account_get_array_by_id( $t_bug['reporter_id'] ); 80 $t_issue_data['summary'] = $t_bug['summary']; 81 $t_issue_data['version'] = mci_null_if_empty( $t_bug['version'] ); 82 $t_issue_data['build'] = mci_null_if_empty( $t_bug['build'] ); 83 $t_issue_data['platform'] = mci_null_if_empty( $t_bug['platform'] ); 84 $t_issue_data['os'] = mci_null_if_empty( $t_bug['os'] ); 85 $t_issue_data['os_build'] = mci_null_if_empty( $t_bug['os_build'] ); 86 $t_issue_data['reproducibility'] = mci_enum_get_array_by_id( $t_bug['reproducibility'], 'reproducibility', $t_lang ); 87 $t_issue_data['date_submitted'] = timestamp_to_iso8601( $t_bug['date_submitted'] ); 88 89 $t_issue_data['sponsorship_total'] = $t_bug['sponsorship_total']; 90 91 if( !empty( $t_bug['handler_id'] ) ) { 92 $t_issue_data['handler'] = mci_account_get_array_by_id( $t_bug['handler_id'] ); 93 } 94 $t_issue_data['projection'] = mci_enum_get_array_by_id( $t_bug['projection'], 'projection', $t_lang ); 95 $t_issue_data['eta'] = mci_enum_get_array_by_id( $t_bug['eta'], 'eta', $t_lang ); 96 97 $t_issue_data['resolution'] = mci_enum_get_array_by_id( $t_bug['resolution'], 'resolution', $t_lang ); 98 $t_issue_data['fixed_in_version'] = mci_null_if_empty( $t_bug['fixed_in_version'] ); 99 100 $t_issue_data['description'] = $t_bug['description']; 101 $t_issue_data['steps_to_reproduce'] = mci_null_if_empty( $t_bug['steps_to_reproduce'] ); 102 $t_issue_data['additional_information'] = mci_null_if_empty( $t_bug['additional_information'] ); 103 104 $t_issue_data['attachments'] = mci_issue_get_attachments( $p_issue_id ); 105 $t_issue_data['relationships'] = mci_issue_get_relationships( $p_issue_id, $t_user_id ); 106 $t_issue_data['notes'] = mci_issue_get_notes( $p_issue_id ); 107 $t_issue_data['custom_fields'] = mci_issue_get_custom_fields( $p_issue_id ); 108 109 return $t_issue_data; 110 } 111 112 /** 113 * Sets the supplied array of custom field values to the specified issue id. 114 * 115 * @param $p_issue_id Issue id to apply custom field values to. 116 * @param $p_custom_fields The array of custom field values as described in the webservice complex types. 117 */ 118 function mci_issue_set_custom_fields( $p_issue_id, &$p_custom_fields ) { 119 # set custom field values on the submitted issue 120 if ( isset( $p_custom_fields ) && is_array( $p_custom_fields ) ) { 121 foreach( $p_custom_fields as $t_custom_field ) { 122 # get custom field id from object ref 123 $t_custom_field_id = mci_get_custom_field_id_from_objectref( $t_custom_field['field'] ); 124 125 if ( $t_custom_field_id == 0 ) { 126 return new soap_fault( 'Client', '', 'Custom field ' . $t_custom_field['field']['name'] . ' not found' ); 127 } 128 129 # skip if current user doesn't have login access. 130 if ( !custom_field_has_write_access( $t_custom_field_id, $p_issue_id ) ) { 131 continue; 132 } 133 134 $t_value = $t_custom_field['value']; 135 136 if ( !custom_field_validate( $t_custom_field_id, $t_value ) ) { 137 return new soap_fault( 'Client', '', 'Invalid custom field value for field id ' . $t_custom_field_id ); 138 } 139 140 if ( !custom_field_set_value( $t_custom_field_id, $p_issue_id, $t_value ) ) { 141 return new soap_fault( 'Server', '', 'Unable to set custom field value for field id ' . $t_custom_field_id . ' to issue ' . $p_issue_id ); 142 } 143 } 144 } 145 } 146 147 /** 148 * Get the custom field values associated with the specified issue id. 149 * 150 * @param $p_issue_id Issue id to get the custom field values for. 151 * 152 * @return null if no custom field defined for the project that contains the issue, or if no custom 153 * fields are accessible to the current user. 154 */ 155 function mci_issue_get_custom_fields( $p_issue_id ) { 156 $t_project_id = bug_get_field( $p_issue_id, 'project_id' ); 157 158 $t_custom_fields = array(); 159 $t_related_custom_field_ids = custom_field_get_linked_ids( $t_project_id ); 160 161 foreach( $t_related_custom_field_ids as $t_id ) { 162 $t_def = custom_field_get_definition( $t_id ); 163 164 if ( custom_field_has_read_access( $t_id, $p_issue_id ) ) { 165 # user has not access to read this custom field. 166 $t_value = custom_field_get_value( $t_id, $p_issue_id ); 167 if ( $t_value === false ) { 168 continue; 169 } 170 171 $t_custom_field_value = array(); 172 $t_custom_field_value['field'] = array(); 173 $t_custom_field_value['field']['id'] = $t_id; 174 $t_custom_field_value['field']['name'] = $t_def['name']; 175 $t_custom_field_value['value'] = $t_value; 176 177 $t_custom_fields[] = $t_custom_field_value; 178 } 179 } # foreach 180 181 return ( sizeof( $t_custom_fields ) == 0 ? null : $t_custom_fields ); 182 } 183 184 /** 185 * Get the attachments of an issue. 186 * 187 * @param integer $p_issue_id The id of the issue to retrieve the attachments for 188 * @return Array that represents an AttachmentData structure 189 */ 190 function mci_issue_get_attachments( $p_issue_id ) { 191 $t_attachment_rows = bug_get_attachments( $p_issue_id ); 192 $t_result = array(); 193 194 foreach( $t_attachment_rows as $t_attachment_row ) { 195 $t_attachment = array(); 196 $t_attachment['id'] = $t_attachment_row['id']; 197 $t_attachment['filename'] = $t_attachment_row['filename']; 198 $t_attachment['size'] = $t_attachment_row['filesize']; 199 $t_attachment['content_type'] = $t_attachment_row['file_type']; 200 $t_attachment['date_submitted'] = timestamp_to_iso8601( db_unixtimestamp( $t_attachment_row['date_added'] ) ); 201 $t_attachment['download_url'] = mci_get_mantis_path() . 'file_download.php?file_id=' . $t_attachment_row['id'] . '&type=bug'; 202 $t_result[] = $t_attachment; 203 } 204 205 return $t_result; 206 } 207 208 /** 209 * Get the relationships of an issue. 210 * 211 * @param integer $p_issue_id The id of the issue to retrieve the relationships for 212 * @return Array that represents an RelationShipData structure 213 */ 214 function mci_issue_get_relationships( $p_issue_id, $p_user_id ) { 215 $t_relationships = array(); 216 217 $t_src_relationships = relationship_get_all_src( $p_issue_id ); 218 foreach( $t_src_relationships as $t_relship_row) { 219 if ( access_has_bug_level( config_get( 'mc_readonly_access_level_threshold' ), $t_relship_row->dest_bug_id, $p_user_id ) ) { 220 $t_relationship = array(); 221 $t_reltype = array(); 222 $t_relationship['id'] = $t_relship_row->id; 223 $t_reltype['id'] = $t_relship_row->type; 224 $t_reltype['name'] = relationship_get_description_src_side($t_relship_row->type); 225 $t_relationship['type'] = $t_reltype; 226 $t_relationship['target_id'] = $t_relship_row->dest_bug_id; 227 $t_relationships[] = $t_relationship; 228 } 229 } 230 231 $t_dest_relationships = relationship_get_all_dest( $p_issue_id ); 232 foreach( $t_dest_relationships as $t_relship_row) { 233 if ( access_has_bug_level( config_get( 'mc_readonly_access_level_threshold' ), $t_relship_row->src_bug_id, $p_user_id ) ) { 234 $t_relationship = array(); 235 $t_relationship['id'] = $t_relship_row->id; 236 $t_reltype = array(); 237 $t_reltype['id'] = $t_relship_row->type; 238 $t_reltype['name'] = relationship_get_description_dest_side($t_relship_row->type); 239 $t_relationship['type'] = $t_reltype; 240 $t_relationship['target_id'] = $t_relship_row->src_bug_id; 241 $t_relationships[] = $t_relationship; 242 } 243 } 244 245 return $t_relationships; 246 } 247 248 /** 249 * Get all visible notes for a specific issue 250 * 251 * @param integer $p_issue_id The id of the issue to retrieve the notes for 252 * @return Array that represents an IssueNoteData structure 253 */ 254 function mci_issue_get_notes( $p_issue_id ) { 255 $t_user_id = auth_get_current_user_id(); 256 $t_lang = mci_get_user_lang( $t_user_id ); 257 $t_project_id = bug_get_field( $p_issue_id, 'project_id' ); 258 $t_user_access_level = user_get_access_level( $t_user_id, $t_project_id ); 259 $t_user_bugnote_order = 'ASC'; // always get the notes in ascending order for consistency to the calling application. 260 261 $t_result = array(); 262 foreach( bugnote_get_all_visible_bugnotes( $p_issue_id, $t_user_access_level, $t_user_bugnote_order, 0 ) as $t_value ) { 263 $t_bugnote = array(); 264 $t_bugnote['id'] = $t_value->id; 265 $t_bugnote['reporter'] = mci_account_get_array_by_id( $t_value->reporter_id ); 266 $t_bugnote['date_submitted'] = timestamp_to_iso8601( $t_value->date_submitted ); 267 $t_bugnote['last_modified'] = timestamp_to_iso8601( $t_value->last_modified ); 268 $t_bugnote['text'] = $t_value->note; 269 $t_bugnote['view_state'] = mci_enum_get_array_by_id( $t_value->view_state, 'view_state', $t_lang ); 270 $t_result[] = $t_bugnote; 271 } 272 273 return $t_result; 274 } 275 276 /** 277 * Get the biggest issue id currently used. 278 * 279 * @param string $p_username The name of the user trying to retrieve the information 280 * @param string $p_password The password of the user. 281 * @param int $p_project_id -1 default project, 0 for all projects, otherwise project id. 282 * @return integer The biggest used issue id. 283 */ 284 function mc_issue_get_biggest_id( $p_username, $p_password, $p_project_id ) { 285 $t_user_id = mci_check_login( $p_username, $p_password ); 286 if ( $t_user_id === false ) { 287 return new soap_fault( 'Client', '', 'Access Denied' ); 288 } 289 290 $t_any = defined( 'META_FILTER_ANY' ) ? META_FILTER_ANY : 'any'; 291 $t_none = defined( 'META_FILTER_NONE' ) ? META_FILTER_NONE : 'none'; 292 293 $t_filter = array( 294 'show_category' => Array ( '0' => $t_any ), 295 'show_severity' => Array ( '0' => $t_any ), 296 'show_status' => Array ( '0' => $t_any ), 297 'highlight_changed' => 0, 298 'reporter_id' => Array ( '0' => $t_any ), 299 'handler_id' => Array ( '0' => $t_any ), 300 'show_resolution' => Array ( '0' => $t_any ), 301 'show_build' => Array ( '0' => $t_any ), 302 'show_version' => Array ( '0' => $t_any ), 303 'hide_status' => Array ( '0' => $t_none ), 304 'user_monitor' => Array ( '0' => $t_any ), 305 'dir' => 'DESC', 306 'sort' => 'date_submitted' 307 ); 308 309 $t_page_number = 1; 310 $t_per_page = 1; 311 $t_bug_count = 0; 312 313 # Get project id, if -1, then retrieve the current which will be the default since there is no cookie. 314 $t_project_id = $p_project_id; 315 if ( $t_project_id == -1 ) { 316 $t_project_id = helper_get_current_project(); 317 } 318 319 if ( ( $t_project_id > 0 ) && !project_exists( $t_project_id ) ) { 320 return new soap_fault( 'Client', '', "Project '$t_project_id' does not exist." ); 321 } 322 323 if ( !mci_has_readonly_access( $t_user_id, $t_project_id ) ) { 324 return new soap_fault( 'Client', '', 'Access Denied' ); 325 } 326 327 $t_rows = filter_get_bug_rows( $t_page_number, $t_per_page, $t_page_count, $t_bug_count, $t_filter, $t_project_id, $t_user_id ); 328 if ( count( $t_rows ) == 0 ) { 329 return 0; 330 } else { 331 return $t_rows[0]['id']; 332 } 333 } 334 335 /** 336 * Get the id of an issue via the issue's summary. 337 * 338 * @param string $p_username The name of the user trying to delete the issue. 339 * @param string $p_password The password of the user. 340 * @param string $p_summary The summary of the issue to retrieve. 341 * @return integer The id of the issue with the given summary, 0 if there is no such issue. 342 */ 343 function mc_issue_get_id_from_summary( $p_username, $p_password, $p_summary ) { 344 $t_user_id = mci_check_login( $p_username, $p_password ); 345 if ( $t_user_id === false ) { 346 return new soap_fault( 'Client', '', 'Access Denied' ); 347 } 348 349 $t_bug_table = config_get( 'mantis_bug_table' ); 350 351 $c_summary = db_prepare_string( $p_summary ); 352 353 $query = "SELECT id 354 FROM $t_bug_table 355 WHERE summary = '$c_summary'"; 356 357 $result = db_query( $query, 1 ); 358 359 if ( db_num_rows( $result ) == 0 ) { 360 return 0; 361 } else { 362 while ( ( $row = db_fetch_array( $result ) ) !== false ) { 363 $t_issue_id = (int)$row['id']; 364 $t_project_id = bug_get_field( $t_issue_id, 'project_id' ); 365 366 if ( mci_has_readonly_access( $t_user_id, $t_project_id ) ) { 367 return $t_issue_id; 368 } 369 } 370 371 // no issue found that belongs to a project that the user has read access to. 372 return 0; 373 } 374 } 375 376 /** 377 * Add an issue to the database. 378 * 379 * @param string $p_username The name of the user trying to add the issue. 380 * @param string $p_password The password of the user. 381 * @param Array $p_issue A IssueData structure containing information about the new issue. 382 * @return integer The id of the created issue. 383 */ 384 function mc_issue_add( $p_username, $p_password, $p_issue ) { 385 $t_user_id = mci_check_login( $p_username, $p_password ); 386 if ( $t_user_id === false ) { 387 return new soap_fault( 'Client', '', 'Access Denied' ); 388 } 389 390 extract( $p_issue, EXTR_PREFIX_ALL, 'v' ); 391 392 $t_project_id = mci_get_project_id( $v_project ); 393 394 if ( !mci_has_readwrite_access( $t_user_id, $t_project_id ) ) { 395 return new soap_fault( 'Client', '', 'Access Denied' ); 396 } 397 398 $t_handler_id = mci_get_user_id( $v_handler ); 399 $t_priority_id = mci_get_priority_id( $v_priority ); 400 $t_severity_id = mci_get_severity_id( $v_severity ); 401 $t_status_id = mci_get_status_id( $v_status ); 402 $t_reproducibility_id = mci_get_reproducibility_id( $v_reproducibility ); 403 $t_resolution_id = mci_get_resolution_id( $v_resolution ); 404 $t_projection_id = mci_get_projection_id( $v_projection ); 405 $t_eta_id = mci_get_eta_id( $v_eta ); 406 $t_view_state_id = mci_get_view_state_id( $v_view_state ); 407 408 $t_reporter_id = mci_get_user_id( $v_reporter ); 409 if ( $t_reporter_id == 0 ) { 410 $t_reporter_id = $t_user_id; 411 } else { 412 if ( $t_reporter_id != $t_user_id ) { 413 # Make sure that active user has access level required to specify a different reporter. 414 $t_specify_reporter_access_level = config_get( 'mc_specify_reporter_on_add_access_level_threshold' ); 415 if ( !access_has_project_level( $t_specify_reporter_access_level, $t_project_id, $t_user_id ) ) { 416 return new soap_fault( 'Client', '', "Active user does not have access level required to specify a different issue reporter." ); 417 } 418 } 419 } 420 421 if ( ( $t_project_id == 0 ) || !project_exists( $t_project_id ) ) { 422 if ( $t_project_id == 0 ) { 423 return new soap_fault( 'Client', '', "Project '" . $v_project['name'] . "' does not exist." ); 424 } else { 425 return new soap_fault( 'Client', '', "Project '$t_project_id' does not exist." ); 426 } 427 } 428 429 if ( !access_has_project_level( config_get( 'report_bug_threshold' ), $t_project_id, $t_user_id ) ) { 430 return new soap_fault( 'Client', '', "User '$t_user_id' does not have access right to report issues." ); 431 } 432 433 #if ( !access_has_project_level( config_get( 'report_bug_threshold' ), $t_project_id ) || 434 # !access_has_project_level( config_get( 'report_bug_threshold' ), $t_project_id, $v_reporter ) ) { 435 # return new soap_fault( 'Client', '', "User does not have access right to report issues." ); 436 #} 437 438 if ( ( $t_handler_id != 0 ) && !user_exists( $t_handler_id ) ) { 439 return new soap_fault( 'Client', '', "User '$t_handler_id' does not exist." ); 440 } 441 442 if ( !in_array( $v_category, mci_category_get_all_rows( $t_project_id, $t_user_id ) ) ) { 443 $t_error_when_category_not_found = config_get( 'mc_error_when_category_not_found' ); 444 if ( $t_error_when_category_not_found == ON ) { 445 if ( is_blank( $v_category ) && ( count( category_get_all_rows( $t_project_id ) ) == 0 ) ) { 446 $v_category = ''; // it is ok to have category as empty if project has no categories 447 } else { 448 return new soap_fault( 'Client', '', "Category '$v_category' does not exist in project '$t_project_id'." ); 449 } 450 } else { 451 $t_category_when_not_found = config_get( 'mc_category_when_not_found' ); 452 $v_category = $t_category_when_not_found; 453 } 454 } 455 456 if ( isset( $v_version ) && !is_blank( $v_version ) && !version_get_id( $v_version, $t_project_id ) ) { 457 $t_error_when_version_not_found = config_get( 'mc_error_when_version_not_found' ); 458 if ( $t_error_when_version_not_found == ON ) { 459 $t_project_name = project_get_name( $t_project_id ); 460 return new soap_fault( 'Client', '', "Version '$v_version' does not exist in project '$t_project_name'." ); 461 } else { 462 $t_version_when_not_found = config_get( 'mc_version_when_not_found' ); 463 $v_version = $t_version_when_not_found; 464 } 465 } 466 467 if ( is_blank( $v_summary ) ) { 468 return new soap_fault( 'Client', '', "Mandatory field 'summary' is missing." ); 469 } 470 471 if ( is_blank( $v_description ) ) { 472 return new soap_fault( 'Client', '', "Mandatory field 'description' is missing." ); 473 } 474 475 if ( $v_priority == 0 ) { 476 $v_priority = config_get( 'default_bug_priority' ); 477 } 478 479 if ( $v_severity == 0 ) { 480 $v_severity = config_get( 'default_bug_severity' ); 481 } 482 483 if ( $v_view_state == 0 ) { 484 $v_view_state = config_get( 'default_bug_view_status' ); 485 } 486 487 if ( $v_reproducibility == 0 ) { 488 $v_reproducibility = 10; 489 } 490 491 $t_bug_data = new BugData; 492 $t_bug_data->project_id = $t_project_id; 493 $t_bug_data->reporter_id = $t_reporter_id; 494 $t_bug_data->handler_id = $t_handler_id; 495 $t_bug_data->priority = $t_priority_id; 496 $t_bug_data->severity = $t_severity_id; 497 $t_bug_data->reproducibility = $t_reproducibility_id; 498 $t_bug_data->status = $t_status_id; 499 $t_bug_data->resolution = $t_resolution_id; 500 $t_bug_data->projection = $t_projection_id; 501 $t_bug_data->category = $v_category; 502 $t_bug_data->date_submitted = isset( $v_date_submitted ) ? $v_date_submitted : ''; 503 $t_bug_data->last_updated = isset( $v_last_updated ) ? $v_last_updated : ''; 504 $t_bug_data->eta = $t_eta_id; 505 $t_bug_data->os = isset( $v_os ) ? $v_os : ''; 506 $t_bug_data->os_build = isset( $v_os_build ) ? $v_os_build : ''; 507 $t_bug_data->platform = isset( $v_platform ) ? $v_platform : ''; 508 $t_bug_data->version = isset( $v_version ) ? $v_version : ''; 509 $t_bug_data->fixed_in_version = isset( $v_fixed_in_version ) ? $v_fixed_in_version : ''; 510 $t_bug_data->build = isset( $v_build ) ? $v_build : ''; 511 $t_bug_data->view_state = $t_view_state_id; 512 $t_bug_data->summary = $v_summary; 513 $t_bug_data->sponsorship_total = isset( $v_sponsorship_total ) ? $v_sponsorship_total : 0; 514 515 # omitted: 516 # var $bug_text_id 517 # $t_bug_data->profile_id; 518 519 # extended info 520 $t_bug_data->description = $v_description; 521 $t_bug_data->steps_to_reproduce = isset( $v_steps_to_reproduce ) ? $v_steps_to_reproduce : ''; 522 $t_bug_data->additional_information = isset( $v_additional_information ) ? $v_additional_information : ''; 523 524 # submit the issue 525 $t_issue_id = bug_create( $t_bug_data ); 526 527 mci_issue_set_custom_fields( $t_issue_id, $v_custom_fields ); 528 529 if ( isset( $v_notes ) && is_array( $v_notes ) ) { 530 foreach( $v_notes as $t_note ) { 531 if ( isset( $t_note['view_state'] ) ) { 532 $t_view_state = $t_note['view_state']; 533 } else { 534 $t_view_state = config_get( 'default_bugnote_view_status' ); 535 } 536 537 $t_view_state_id = mci_get_enum_id_from_objectref( 'view_state', $t_view_state ); 538 bugnote_add( $t_issue_id, $t_note['text'], '0:00', $t_view_state_id == VS_PRIVATE, BUGNOTE, '', $t_user_id ); 539 } 540 } 541 542 email_new_bug( $t_issue_id ); 543 544 return $t_issue_id; 545 } 546 547 /** 548 * Update Issue in database 549 * 550 * Created By KGB 551 * @param string $p_username The name of the user trying to add the issue. 552 * @param string $p_password The password of the user. 553 * @param Array $p_issue A IssueData structure containing information about the new issue. 554 * @return integer The id of the created issue. 555 */ 556 function mc_issue_update( $p_username, $p_password, $p_issue_id, $p_issue ) { 557 $t_user_id = mci_check_login( $p_username, $p_password ); 558 if ( $t_user_id === false ) { 559 return new soap_fault( 'Client', '', 'Access Denied' ); 560 } 561 562 if ( !bug_exists( $p_issue_id ) ) { 563 return new soap_fault( 'Server', '', "Issue '$p_issue_id' does not exist." ); 564 } 565 566 $t_project_id = bug_get_field( $p_issue_id, 'project_id' ); 567 if ( !mci_has_readwrite_access( $t_user_id, $t_project_id ) ) { 568 return new soap_fault( 'Client', '', 'Access Denied' ); 569 } 570 571 extract( $p_issue, EXTR_PREFIX_ALL, 'v' ); 572 573 $t_project_id = mci_get_project_id( $v_project ); 574 $t_handler_id = mci_get_user_id( $v_handler ); 575 $t_priority_id = mci_get_priority_id( $v_priority ); 576 $t_severity_id = mci_get_severity_id( $v_severity ); 577 $t_status_id = mci_get_status_id( $v_status ); 578 $t_reproducibility_id = mci_get_reproducibility_id( $v_reproducibility ); 579 $t_resolution_id = mci_get_resolution_id( $v_resolution ); 580 $t_projection_id = mci_get_projection_id( $v_projection ); 581 $t_eta_id = mci_get_eta_id( $v_eta ); 582 $t_view_state_id = mci_get_view_state_id( $v_view_state ); 583 584 $t_reporter_id = mci_get_user_id( $v_reporter ); 585 if ( $t_reporter_id == 0 ) { 586 $t_reporter_id = $t_user_id; 587 } 588 589 if ( ( $t_project_id == 0 ) || !project_exists( $t_project_id ) ) { 590 if ( $t_project_id == 0 ) { 591 return new soap_fault( 'Client', '', "Project '" . $v_project['name'] . "' does not exist." ); 592 } else { 593 return new soap_fault( 'Client', '', "Project '$t_project_id' does not exist." ); 594 } 595 } 596 597 if ( !access_has_bug_level( config_get( 'update_bug_threshold' ), $p_issue_id, $t_user_id ) ) { 598 return new soap_fault( 'Client', '', "User '$t_user_id' does not have access right to report issues." ); 599 } 600 601 if ( ( $t_handler_id != 0 ) && !user_exists( $t_handler_id ) ) { 602 return new soap_fault( 'Client', '', "User '$t_handler_id' does not exist." ); 603 } 604 605 if ( !in_array( $v_category, mci_category_get_all_rows( $t_project_id, $t_user_id ) ) ) { 606 $t_error_when_category_not_found = config_get( 'mc_error_when_category_not_found' ); 607 if ( $t_error_when_category_not_found == ON ) { 608 if ( is_blank( $v_category ) && ( count( category_get_all_rows( $t_project_id ) ) == 0 ) ) { 609 $v_category = ''; // it is ok to have category as empty if project has no categories 610 } else { 611 return new soap_fault( 'Client', '', "Category '$v_category' does not exist in project '$t_project_id'." ); 612 } 613 } else { 614 $t_category_when_not_found = config_get( 'mc_category_when_not_found' ); 615 $v_category = $t_category_when_not_found; 616 } 617 } 618 619 if ( isset( $v_version ) && !is_blank( $v_version ) && !version_get_id( $v_version, $t_project_id ) ) { 620 $t_error_when_version_not_found = config_get( 'mc_error_when_version_not_found' ); 621 if ( $t_error_when_version_not_found == ON ) { 622 $t_project_name = project_get_name( $t_project_id ); 623 return new soap_fault( 'Client', '', "Version '$v_version' does not exist in project '$t_project_name'." ); 624 } else { 625 $t_version_when_not_found = config_get( 'mc_version_when_not_found' ); 626 $v_version = $t_version_when_not_found; 627 } 628 } 629 630 if ( is_blank( $v_summary ) ) { 631 return new soap_fault( 'Client', '', "Mandatory field 'summary' is missing." ); 632 } 633 634 if ( is_blank( $v_description ) ) { 635 return new soap_fault( 'Client', '', "Mandatory field 'description' is missing." ); 636 } 637 638 if ( $v_priority == 0 ) { 639 $v_priority = config_get( 'default_bug_priority' ); 640 } 641 642 if ( $v_severity == 0 ) { 643 $v_severity = config_get( 'default_bug_severity' ); 644 } 645 646 if ( $v_view_state == 0 ) { 647 $v_view_state = config_get( 'default_bug_view_status' ); 648 } 649 650 if ( $v_reproducibility == 0 ) { 651 $v_reproducibility = 10; 652 } 653 654 $t_bug_data = new BugData; 655 $t_bug_data->project_id = $t_project_id; 656 $t_bug_data->reporter_id = $t_reporter_id; 657 $t_bug_data->handler_id = $t_handler_id; 658 $t_bug_data->priority = $t_priority_id; 659 $t_bug_data->severity = $t_severity_id; 660 $t_bug_data->reproducibility = $t_reproducibility_id; 661 $t_bug_data->status = $t_status_id; 662 $t_bug_data->resolution = $t_resolution_id; 663 $t_bug_data->projection = $t_projection_id; 664 $t_bug_data->category = $v_category; 665 $t_bug_data->date_submitted = isset( $v_date_submitted ) ? $v_date_submitted : ''; 666 $t_bug_data->last_updated = isset( $v_last_updated ) ? $v_last_updated : ''; 667 $t_bug_data->eta = $t_eta_id; 668 $t_bug_data->os = isset( $v_os ) ? $v_os : ''; 669 $t_bug_data->os_build = isset( $v_os_build ) ? $v_os_build : ''; 670 $t_bug_data->platform = isset( $v_platform ) ? $v_platform : ''; 671 $t_bug_data->version = isset( $v_version ) ? $v_version : ''; 672 $t_bug_data->fixed_in_version = isset( $v_fixed_in_version ) ? $v_fixed_in_version : ''; 673 $t_bug_data->build = isset( $v_build ) ? $v_build : ''; 674 $t_bug_data->view_state = $t_view_state_id; 675 $t_bug_data->summary = $v_summary; 676 $t_bug_data->sponsorship_total = isset( $v_sponsorship_total ) ? $v_sponsorship_total : 0; 677 678 # omitted: 679 # var $bug_text_id 680 # $t_bug_data->profile_id; 681 682 # extended info 683 $t_bug_data->description = $v_description; 684 $t_bug_data->steps_to_reproduce = isset( $v_steps_to_reproduce ) ? $v_steps_to_reproduce : ''; 685 $t_bug_data->additional_information = isset( $v_additional_information ) ? $v_additional_information : ''; 686 687 # submit the issue 688 $t_is_success = bug_update($p_issue_id,$t_bug_data,true,false ); 689 690 mci_issue_set_custom_fields( $p_issue_id, $v_custom_fields ); 691 692 if ( isset( $v_notes ) && is_array( $v_notes ) ) { 693 foreach( $v_notes as $t_note ) { 694 if ( isset( $t_note['view_state'] ) ) { 695 $t_view_state = $t_note['view_state']; 696 } else { 697 $t_view_state = config_get( 'default_bugnote_view_status' ); 698 } 699 700 // TODO: consider supporting updating of bugnotes and detecting the ones that haven't changed. 701 $t_view_state_id = mci_get_enum_id_from_objectref( 'view_state', $t_view_state ); 702 bugnote_add( $p_issue_id, $t_note['text'], '0:00', $t_view_state_id == VS_PRIVATE, BUGNOTE, '', $t_user_id ); 703 } 704 } 705 706 return $t_is_success; 707 } 708 709 /** 710 * Delete the specified issue. 711 * 712 * @param string $p_username The name of the user trying to delete the issue. 713 * @param string $p_password The password of the user. 714 * @param integer $p_issue_id The id of the issue to delete. 715 * @return boolean True if the issue has been deleted successfully, false otherwise. 716 */ 717 function mc_issue_delete( $p_username, $p_password, $p_issue_id ) { 718 $t_user_id = mci_check_login( $p_username, $p_password ); 719 if ( $t_user_id === false ) { 720 return new soap_fault( 'Client', '', 'Access Denied' ); 721 } 722 723 if ( !bug_exists( $p_issue_id ) ) { 724 return new soap_fault( 'Server', '', "Issue '$p_issue_id' does not exist." ); 725 } 726 727 $t_project_id = bug_get_field( $p_issue_id, 'project_id' ); 728 if ( !mci_has_readwrite_access( $t_user_id, $t_project_id ) ) { 729 return new soap_fault( 'Client', '', 'Access Denied' ); 730 } 731 732 return bug_delete( $p_issue_id ); 733 } 734 735 /** 736 * Add a note to an existing issue. 737 * 738 * @param string $p_username The name of the user trying to add a note to an issue. 739 * @param string $p_password The password of the user. 740 * @param integer $p_issue_id The id of the issue to add the note to. 741 * @param IssueNoteData $p_note The note to add. 742 * @return integer The id of the added note. 743 */ 744 function mc_issue_note_add( $p_username, $p_password, $p_issue_id, $p_note ) { 745 $t_user_id = mci_check_login( $p_username, $p_password ); 746 if ( $t_user_id === false ) { 747 return new soap_fault( 'Client', '', 'Access Denied' ); 748 } 749 750 if ( (integer)$p_issue_id < 1 ) { 751 return new soap_fault( 'Client', '', "Invalid issue id '$p_issue_id'." ); 752 } 753 754 if ( !bug_exists( $p_issue_id ) ) { 755 return new soap_fault( 'Client', '', "Issue '$p_issue_id' does not exist" ); 756 } 757 758 $t_project_id = bug_get_field( $p_issue_id, 'project_id' ); 759 if ( !mci_has_readwrite_access( $t_user_id, $t_project_id ) ) { 760 return new soap_fault( 'Client', '', 'Access Denied' ); 761 } 762 763 if ( !access_has_bug_level( config_get( 'add_bugnote_threshold' ), $p_issue_id, $t_user_id ) ) { 764 return new soap_fault( 'Client', '', "User '$t_user_id' does not have access right to add notes to this issue." ); 765 } 766 767 if ( bug_is_readonly( $p_issue_id ) ) { 768 return new soap_fault( 'Client', '', "Issue '$p_issue_id' is readonly." ); 769 } 770 771 if ( isset( $p_note['view_state'] ) ) { 772 $t_view_state = $p_note['view_state']; 773 } else { 774 $t_view_state = config_get( 'default_bug_view_status' ); 775 } 776 777 $t_view_state_id = mci_get_enum_id_from_objectref( 'view_state', $t_view_state ); 778 return bugnote_add( $p_issue_id, $p_note['text'], '0:00', $t_view_state_id == VS_PRIVATE, BUGNOTE, '', $t_user_id ); 779 } 780 781 /** 782 * Delete a note given its id. 783 * 784 * @param string $p_username The name of the user trying to add a note to an issue. 785 * @param string $p_password The password of the user. 786 * @param integer $p_issue_note_id The id of the note to be deleted. 787 * @return true: success, false: failure 788 */ 789 function mc_issue_note_delete( $p_username, $p_password, $p_issue_note_id ) { 790 $t_user_id = mci_check_login( $p_username, $p_password ); 791 if ( $t_user_id === false ) { 792 return new soap_fault( 'Client', '', 'Access Denied' ); 793 } 794 795 if ( (integer)$p_issue_note_id < 1 ) { 796 return new soap_fault( 'Client', '', "Invalid issue note id '$p_issue_note_id'." ); 797 } 798 799 if ( !bugnote_exists( $p_issue_note_id ) ) { 800 return new soap_fault( 'Server', '', "Issue note '$p_issue_note_id' does not exist." ); 801 } 802 803 $t_issue_id = bugnote_get_field( $p_issue_note_id, 'bug_id' ); 804 $t_project_id = bug_get_field( $t_issue_id, 'project_id' ); 805 if ( !mci_has_readwrite_access( $t_user_id, $t_project_id ) ) { 806 return new soap_fault( 'Client', '', 'Access Denied' ); 807 } 808 809 return bugnote_delete( $p_issue_note_id ); 810 } 811 812 /** 813 * Submit a new relationship. 814 * 815 * @param string $p_username The name of the user trying to add a note to an issue. 816 * @param string $p_password The password of the user. 817 * @param integer $p_issue_id The id of the issue of the source issue. 818 * @param RelationshipData $p_relationship The relationship to add. 819 * @return integer The id of the added relationship. 820 */ 821 function mc_issue_relationship_add( $p_username, $p_password, $p_issue_id, $p_relationship ) { 822 $t_user_id = mci_check_login( $p_username, $p_password ); 823 $t_dest_issue_id = $p_relationship['target_id']; 824 $t_rel_type = $p_relationship['type']; 825 826 if ( $t_user_id === false ) { 827 return new soap_fault( 'Client', '', 'Access Denied' ); 828 } 829 830 $t_project_id = bug_get_field( $p_issue_id, 'project_id' ); 831 if ( !mci_has_readwrite_access( $t_user_id, $t_project_id ) ) { 832 return new soap_fault( 'Client', '', 'Access Denied' ); 833 } 834 835 # user has access to update the bug... 836 if ( !access_has_bug_level( config_get( 'update_bug_threshold' ), $p_issue_id, $t_user_id ) ) { 837 return new soap_fault( 'Client', '', "Active user does not have access level required to add a relationship to this issue." ); 838 } 839 840 # source and destination bugs are the same bug... 841 if ( $p_issue_id == $t_dest_issue_id ) { 842 return new soap_fault( 'Client', '', "An issue can't be related to itself." ); 843 } 844 845 # the related bug exists... 846 if ( !bug_exists( $t_dest_issue_id ) ) { 847 return new soap_fault( 'Client', '', "Issue '$t_dest_issue_id' not found." ); 848 } 849 850 # bug is not read-only... 851 if ( bug_is_readonly( $p_issue_id ) ) { 852 return new soap_fault( 'Client', '', "Issue '$p_issue_id' is readonly." ); 853 } 854 855 # user can access to the related bug at least as viewer... 856 if ( !access_has_bug_level( VIEWER, $t_dest_issue_id, $t_user_id ) ) { 857 return new soap_fault( 'Client', '', "The issue '$t_dest_issue_id' requires higher access level." ); 858 } 859 860 $t_old_id_relationship = relationship_same_type_exists( $p_issue_id, $t_dest_issue_id, $t_rel_type['id'] ); 861 862 if ( $t_old_id_relationship == 0 ) { 863 relationship_add( $p_issue_id, $t_dest_issue_id, $t_rel_type['id'] ); 864 // The above function call into Mantis doesn't seem to return a valid BugRelationshipData object. 865 // So we call db_insert_id in order to find the id of the created relationship. 866 $t_relationship_id = db_insert_id( config_get( 'mantis_bug_relationship_table' ) ); 867 868 # Add log line to the history (both bugs) 869 history_log_event_special( $p_issue_id, BUG_ADD_RELATIONSHIP, $t_rel_type['id'], $t_dest_issue_id ); 870 history_log_event_special( $t_dest_issue_id, BUG_ADD_RELATIONSHIP, relationship_get_complementary_type( $t_rel_type['id'] ), $p_issue_id ); 871 872 # update bug last updated (just for the src bug) 873 bug_update_date( $p_issue_id ); 874 875 # send email notification to the users addressed by both the bugs 876 email_relationship_added( $p_issue_id, $t_dest_issue_id, $t_rel_type['id'] ); 877 email_relationship_added( $t_dest_issue_id, $p_issue_id, relationship_get_complementary_type( $t_rel_type['id'] ) ); 878 879 return $t_relationship_id; 880 } else { 881 return new soap_fault( 'Client', '', "Relationship already exists." ); 882 } 883 } 884 885 /** 886 * Delete the relationship with the specified target id. 887 * 888 * @param string $p_username The name of the user trying to add a note to an issue. 889 * @param string $p_password The password of the user. 890 * @param integer $p_issue_id The id of the source issue for the relationship 891 * @param integer $p_relationship_id The id of relationship to delete. 892 * @return true: success, false: failure 893 */ 894 function mc_issue_relationship_delete( $p_username, $p_password, $p_issue_id, $p_relationship_id ) { 895 $t_user_id = mci_check_login( $p_username, $p_password ); 896 897 if ( $t_user_id === false ) { 898 return new soap_fault( 'Client', '', 'Access Denied' ); 899 } 900 901 $t_project_id = bug_get_field( $p_issue_id, 'project_id' ); 902 if ( !mci_has_readwrite_access( $t_user_id, $t_project_id ) ) { 903 return new soap_fault( 'Client', '', 'Access Denied' ); 904 } 905 906 # user has access to update the bug... 907 if ( !access_has_bug_level( config_get( 'update_bug_threshold' ), $p_issue_id, $t_user_id ) ) { 908 return new soap_fault( 'Client', '', "Active user does not have access level required to remove a relationship from this issue." ); 909 } 910 911 # bug is not read-only... 912 if ( bug_is_readonly( $p_issue_id ) ) { 913 return new soap_fault( 'Client', '', "Issue '$p_issue_id' is readonly." ); 914 } 915 916 # retrieve the destination bug of the relationship 917 $t_dest_issue_id = relationship_get_linked_bug_id( $p_relationship_id, $p_issue_id ); 918 919 # user can access to the related bug at least as viewer, if it's exist... 920 if ( bug_exists( $t_dest_issue_id )) { 921 if ( !access_has_bug_level( VIEWER, $t_dest_issue_id, $t_user_id ) ) { 922 return new soap_fault( 'Client', '', "The issue '$t_dest_issue_id' requires higher access level." ); 923 } 924 } 925 926 $t_bug_relationship_data = relationship_get( $p_relationship_id ); 927 $t_rel_type = $t_bug_relationship_data->type; 928 929 # delete relationship from the DB 930 relationship_delete( $p_relationship_id ); 931 932 # update bug last updated (just for the src bug) 933 bug_update_date( $p_issue_id ); 934 935 # set the rel_type for both bug and dest_bug based on $t_rel_type and on who is the dest bug 936 if ($p_issue_id == $t_bug_relationship_data->src_bug_id) { 937 $t_bug_rel_type = $t_rel_type; 938 $t_dest_bug_rel_type = relationship_get_complementary_type( $t_rel_type ); 939 } else { 940 $t_bug_rel_type = relationship_get_complementary_type( $t_rel_type ); 941 $t_dest_bug_rel_type = $t_rel_type; 942 } 943 944 # send email and update the history for the src issue 945 history_log_event_special( $p_issue_id, BUG_DEL_RELATIONSHIP, $t_bug_rel_type, $t_dest_issue_id ); 946 email_relationship_deleted( $p_issue_id, $t_dest_issue_id, $t_bug_rel_type ); 947 948 if ( bug_exists( $t_dest_issue_id )) { 949 # send email and update the history for the dest issue 950 history_log_event_special( $t_dest_issue_id, BUG_DEL_RELATIONSHIP, $t_dest_bug_rel_type, $p_issue_id ); 951 email_relationship_deleted( $t_dest_issue_id, $p_issue_id, $t_dest_bug_rel_type ); 952 } 953 954 return true; 955 } 956 957 /** 958 * Log a checkin event on the issue 959 * 960 * @param string $p_username The name of the user trying to access the issue. 961 * @param string $p_password The password of the user. 962 * @param integer $p_issue_id The id of the issue to log a checkin. 963 * @param string $p_comment The comment to add 964 * @param boolean $p_fixed True if the issue is to be set to fixed 965 * @return boolean true success, false otherwise. 966 */ 967 function mc_issue_checkin( $p_username, $p_password, $p_issue_id, $p_comment, $p_fixed) { 968 $t_user_id = mci_check_login( $p_username, $p_password ); 969 if ( $t_user_id === false ) { 970 return new soap_fault( 'Client', '', 'Access Denied' ); 971 } 972 973 if ( !bug_exists( $p_issue_id ) ) { 974 return new soap_fault( 'Client', '', "Issue '$p_issue_id' not found." ); 975 } 976 977 $t_project_id = bug_get_field( $p_issue_id, 'project_id' ); 978 if ( !mci_has_readwrite_access( $t_user_id, $t_project_id ) ) { 979 return new soap_fault( 'Client', '', 'Access Denied' ); 980 } 981 982 helper_call_custom_function( 'checkin', array( $p_issue_id, $p_comment, '', '', $p_fixed ) ); 983 984 return true; 985 } 986 ?>
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 |
|