Skip to content

Commit

Permalink
Use IssueAddCommand in SOAP API
Browse files Browse the repository at this point in the history
  • Loading branch information
vboctor committed Mar 4, 2018
1 parent fe02d21 commit 51e1233
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 254 deletions.
31 changes: 23 additions & 8 deletions api/soap/mc_api.php
Expand Up @@ -31,6 +31,7 @@

require_api( 'api_token_api.php' );

use Mantis\Exceptions\ClientException;
use Mantis\Exceptions\LegacyApiFaultException;

/**
Expand Down Expand Up @@ -287,12 +288,17 @@ static function faultFromException( Exception $p_exception ) {
* @param stdClass|array $p_object Object.
* @return array
*/
static function objectToArray($p_object ) {
if( is_object( $p_object ) ) {
return get_object_vars( $p_object );
static function objectToArray( $p_object, $p_recursive = false ) {
$t_object = is_object( $p_object ) ? get_object_vars( $p_object ) : $p_object;
if( $p_recursive && is_array( $t_object ) ) {
foreach( $t_object as $t_key => $t_value ) {
if( is_object( $t_object[$t_key] ) || is_array( $t_object[$t_key] ) ) {
$t_object[$t_key] = ApiObjectFactory::objectToArray( $t_object[$t_key], $p_recursive );
}
}
}

return $p_object;
return $t_object;
}

/**
Expand Down Expand Up @@ -353,7 +359,7 @@ static function isFault( $p_maybe_fault ) {
*/
static function throwIfFault( $p_maybe_fault ) {
if( ApiObjectFactory::isFault( $p_maybe_fault ) ) {
throw new LegacyApiFaultException( $p_maybe_fault->fault_string, $p_maybe_fault->status_code );
throw new LegacyApiFaultException( $p_maybe_fault->getMessage(), $p_maybe_fault->getCode() );
}
}
}
Expand Down Expand Up @@ -876,9 +882,10 @@ function mci_get_version( $p_version, $p_project_id ) {
*
* @param string|object $p_version The version string or object with name or id or both.
* @param int $p_project_id The project id.
* @param string $p_field_name Version field name (e.g. version, target_version, fixed_in_version)
* @return int|RestFault|SoapFault The version id, 0 if not supplied.
*/
function mci_get_version_id( $p_version, $p_project_id ) {
function mci_get_version_id( $p_version, $p_project_id, $p_field_name = 'version' ) {
$t_version_id = 0;
$t_version_for_error = '';

Expand All @@ -903,7 +910,11 @@ function mci_get_version_id( $p_version, $p_project_id ) {
$t_error_when_version_not_found = config_get( 'webservice_error_when_version_not_found' );
if( $t_error_when_version_not_found == ON ) {
$t_project_name = project_get_name( $p_project_id );
return ApiObjectFactory::faultBadRequest( "Version '$t_version_for_error' does not exist in project '$t_project_name'." );
throw new ClientException(
"Version '$t_version_for_error' does not exist in project '$t_project_name'.",
ERROR_INVALID_FIELD_VALUE,
array( 'version' )
);
}

$t_version_when_not_found = config_get( 'webservice_version_when_not_found' );
Expand Down Expand Up @@ -983,7 +994,11 @@ function mci_get_category_id( $p_category, $p_project_id ) {
$t_category_id = $fn_get_category_id_internal( $p_category, $p_project_id );
if( $t_category_id == 0 && !config_get( 'allow_no_category' ) ) {
if( !isset( $p_category ) ) {
return ApiObjectFactory::faultBadRequest( 'Category field must be supplied.' );
throw new ClientException(
'Category field must be supplied.',
ERROR_EMPTY_FIELD,
array( 'category' )
);
}

# category may be a string, array with id, array with name, or array
Expand Down
228 changes: 7 additions & 221 deletions api/soap/mc_issue_api.php
Expand Up @@ -906,228 +906,14 @@ function mc_issue_add( $p_username, $p_password, $p_issue ) {
return mci_fault_login_failed();
}

if( is_object( $p_issue ) ) {
$p_issue = ApiObjectFactory::objectToArray( $p_issue );
}

if( !isset( $p_issue['summary'] ) ) {
return ApiObjectFactory::faultBadRequest( 'Summary not specified' );
}

if( !isset( $p_issue['description'] ) ) {
return ApiObjectFactory::faultBadRequest( 'Description not specified' );
}

if( !isset( $p_issue['project'] ) ) {
return ApiObjectFactory::faultBadRequest( 'Project not specified' );
}

$t_project = $p_issue['project'];

$t_project_id = mci_get_project_id( $t_project );
$g_project_override = $t_project_id; # ensure that helper_get_current_project() calls resolve to this project id

if( !mci_has_readwrite_access( $t_user_id, $t_project_id ) ) {
return mci_fault_access_denied( $t_user_id );
}

$t_handler_id = isset( $p_issue['handler'] ) ? mci_get_user_id( $p_issue['handler'] ) : 0;
$t_priority_id = isset( $p_issue['priority'] ) ? mci_get_priority_id( $p_issue['priority'] ) : config_get( 'default_bug_priority' );
$t_severity_id = isset( $p_issue['severity'] ) ? mci_get_severity_id( $p_issue['severity'] ) : config_get( 'default_bug_severity' );
$t_status_id = isset( $p_issue['status'] ) ? mci_get_status_id( $p_issue['status'] ) : config_get( 'bug_submit_status' );
$t_reproducibility_id = isset( $p_issue['reproducibility'] ) ? mci_get_reproducibility_id( $p_issue['reproducibility'] ) : config_get( 'default_bug_reproducibility' );
$t_resolution_id = isset( $p_issue['resolution'] ) ? mci_get_resolution_id( $p_issue['resolution'] ) : config_get( 'default_bug_resolution' );
$t_projection_id = isset( $p_issue['projection'] ) ? mci_get_projection_id( $p_issue['projection'] ) : config_get( 'default_bug_resolution' );
$t_eta_id = isset( $p_issue['eta'] ) ? mci_get_eta_id( $p_issue['eta'] ) : config_get( 'default_bug_eta' );
$t_view_state_id = isset( $p_issue['view_state'] ) ? mci_get_view_state_id( $p_issue['view_state'] ) : config_get( 'default_bug_view_status' );
$t_summary = $p_issue['summary'];
$t_description = $p_issue['description'];
$t_notes = isset( $p_issue['notes'] ) ? $p_issue['notes'] : array();

# TODO: #17777: Add test case for mc_issue_add() and mc_issue_note_add() reporter override
if( isset( $p_issue['reporter'] ) ) {
$t_reporter_id = mci_get_user_id( $p_issue['reporter'] );

if( $t_reporter_id != $t_user_id ) {
# Make sure that active user has access level required to specify a different reporter.
$t_specify_reporter_access_level = config_get( 'webservice_specify_reporter_on_add_access_level_threshold' );
if( !access_has_project_level( $t_specify_reporter_access_level, $t_project_id, $t_user_id ) ) {
return mci_fault_access_denied( $t_user_id, 'Active user does not have access level required to specify a different issue reporter' );
}
}
} else {
$t_reporter_id = $t_user_id;
}

if( ( $t_project_id == 0 ) || !project_exists( $t_project_id ) ) {
if( $t_project_id != 0 ) {
return ApiObjectFactory::faultNotFound( "Project '" . $t_project->name . "' does not exist." );
}

return ApiObjectFactory::faultNotFound( "Project with id '" . $t_project_id . "' does not exist." );
}

if( !access_has_project_level( config_get( 'report_bug_threshold' ), $t_project_id, $t_user_id ) ) {
return mci_fault_access_denied( $t_user_id, 'User does not have access right to report issues' );
}

$t_access_check_result = mci_issue_handler_access_check( $t_user_id, $t_project_id, /* old */ 0, /* new */ $t_handler_id );
if( $t_access_check_result !== true ) {
return $t_access_check_result;
}

$t_category = isset( $p_issue['category'] ) ? $p_issue['category'] : null;

$t_category_id = mci_get_category_id( $t_category, $t_project_id );
if( ApiObjectFactory::isFault( $t_category_id ) ) {
return $t_category_id;
}

$t_version_id = isset( $p_issue['version'] ) ? mci_get_version_id( $p_issue['version'], $t_project_id ) : 0;
if( ApiObjectFactory::isFault( $t_version_id ) ) {
return $t_version_id;
}

$t_fixed_in_version_id = isset( $p_issue['fixed_in_version'] ) ? mci_get_version_id( $p_issue['fixed_in_version'], $t_project_id ) : 0;
if( ApiObjectFactory::isFault( $t_fixed_in_version_id ) ) {
return $t_fixed_in_version_id;
}

$t_target_version_id = isset( $p_issue['target_version'] ) ? mci_get_version_id( $p_issue['target_version'], $t_project_id ) : 0;
if( ApiObjectFactory::isFault( $t_target_version_id ) ) {
return $t_target_version_id;
}

if( is_blank( $t_summary ) ) {
return ApiObjectFactory::faultBadRequest( 'Mandatory field \'summary\' is missing.' );
}

if( is_blank( $t_description ) ) {
return ApiObjectFactory::faultBadRequest( 'Mandatory field \'description\' is missing.' );
}

$t_bug_data = new BugData;
$t_bug_data->profile_id = 0;
$t_bug_data->project_id = $t_project_id;
$t_bug_data->reporter_id = $t_reporter_id;
$t_bug_data->handler_id = $t_handler_id;
$t_bug_data->priority = $t_priority_id;
$t_bug_data->severity = $t_severity_id;
$t_bug_data->reproducibility = $t_reproducibility_id;
$t_bug_data->status = $t_status_id;
$t_bug_data->resolution = $t_resolution_id;
$t_bug_data->projection = $t_projection_id;
$t_bug_data->category_id = $t_category_id;
$t_bug_data->date_submitted = isset( $p_issue['date_submitted'] ) ? strtotime( $p_issue['date_submitted'] ) : '';
$t_bug_data->last_updated = isset( $p_issue['last_updated'] ) ? strtotime( $p_issue['last_updated'] ) : '';
$t_bug_data->eta = $t_eta_id;
$t_bug_data->profile_id = isset( $p_issue['profile_id'] ) ? $p_issue['profile_id'] : 0;
$t_bug_data->os = isset( $p_issue['os'] ) ? $p_issue['os'] : '';
$t_bug_data->os_build = isset( $p_issue['os_build'] ) ? $p_issue['os_build'] : '';
$t_bug_data->platform = isset( $p_issue['platform'] ) ? $p_issue['platform'] : '';

if( $t_version_id != 0 ) {
$t_bug_data->version = version_get_field( $t_version_id, 'version' );
}

if( $t_fixed_in_version_id != 0 ) {
$t_bug_data->fixed_in_version = version_get_field( $t_fixed_in_version_id, 'version' );
}

if( $t_target_version_id != 0 && access_has_project_level( config_get( 'roadmap_update_threshold' ), $t_bug_data->project_id, $t_user_id ) ) {
$t_bug_data->target_version = version_get_field( $t_target_version_id, 'version' );
}

$t_bug_data->build = isset( $p_issue['build'] ) ? $p_issue['build'] : '';
$t_bug_data->view_state = $t_view_state_id;
$t_bug_data->summary = $t_summary;
$t_bug_data->sponsorship_total = isset( $p_issue['sponsorship_total'] ) ? $p_issue['sponsorship_total'] : 0;
if( isset( $p_issue['sticky'] ) &&
access_has_project_level( config_get( 'set_bug_sticky_threshold', null, null, $t_project_id ), $t_project_id ) ) {
$t_bug_data->sticky = $p_issue['sticky'];
}

if( isset( $p_issue['due_date'] ) &&
access_has_project_level( config_get( 'due_date_update_threshold' ), $t_bug_data->project_id ) ) {
$t_bug_data->due_date = strtotime( $p_issue['due_date'] );
} else {
$t_bug_data->due_date = date_get_null();
}

# omitted:
# var $bug_text_id
# $t_bug_data->profile_id;
# extended info
$t_bug_data->description = $t_description;
$t_bug_data->steps_to_reproduce = isset( $p_issue['steps_to_reproduce'] ) ? $p_issue['steps_to_reproduce'] : '';
$t_bug_data->additional_information = isset( $p_issue['additional_information'] ) ? $p_issue['additional_information'] : '';

# submit the issue
$t_issue_id = $t_bug_data->create();
$t_bug_data->process_mentions();

log_event( LOG_WEBSERVICE, 'created new issue id \'' . $t_issue_id . '\'' );

$t_cf_result = mci_project_custom_fields_validate( $t_project_id, $p_issue['custom_fields'] );
if( ApiObjectFactory::isFault( $t_cf_result ) ) {
return $t_cf_result;
}

$t_set_custom_field_error = mci_issue_set_custom_fields( $t_issue_id, $p_issue['custom_fields'], false );
if( $t_set_custom_field_error != null ) {
return $t_set_custom_field_error;
}

if( isset( $p_issue['monitors'] ) ) {
mci_issue_set_monitors( $t_issue_id, $t_user_id, $p_issue['monitors'] );
}

if( isset( $t_notes ) && is_array( $t_notes ) ) {
foreach( $t_notes as $t_note ) {
$t_note = ApiObjectFactory::objectToArray( $t_note );

if( isset( $t_note['view_state'] ) ) {
$t_view_state = $t_note['view_state'];
} else {
$t_view_state = config_get( 'default_bugnote_view_status' );
}

$t_note_type = isset( $t_note['note_type'] ) ? (int)$t_note['note_type'] : BUGNOTE;
$t_note_attr = isset( $t_note['note_type'] ) ? $t_note['note_attr'] : '';

$t_view_state_id = mci_get_enum_id_from_objectref( 'view_state', $t_view_state );
$t_note_id = bugnote_add(
$t_issue_id,
$t_note['text'],
mci_get_time_tracking_from_note( $t_issue_id, $t_note ),
$t_view_state_id == VS_PRIVATE,
$t_note_type,
$t_note_attr,
$t_user_id,
false ); # don't send mail

bugnote_process_mentions( $t_issue_id, $t_note_id, $t_note['text'] );

log_event( LOG_WEBSERVICE, 'bugnote id \'' . $t_note_id . '\' added to issue \'' . $t_issue_id . '\'' );
}
}

if( isset( $p_issue['tags'] ) && is_array( $p_issue['tags'] ) ) {
$t_tags_result = mci_tag_set_for_issue( $t_issue_id, $p_issue['tags'], $t_user_id );
if( ApiObjectFactory::isFault( $t_tags_result ) ) {
return $t_tags_result;
}
}

email_bug_added( $t_issue_id );

if( $t_bug_data->status != config_get( 'bug_submit_status' ) ) {
history_log_event( $t_issue_id, 'status', config_get( 'bug_submit_status' ) );
}
$t_issue = ApiObjectFactory::objectToArray( $p_issue, /* recursive */ true );
$t_data = array(
'payload' => array( 'issue' => $t_issue )
);

if( $t_bug_data->resolution != config_get( 'default_bug_resolution' ) ) {
history_log_event( $t_issue_id, 'resolution', config_get( 'default_bug_resolution' ) );
}
$t_command = new IssueAddCommand( $t_data );
$t_result = $t_command->execute();
$t_issue_id = (int)$t_result['issue_id'];

return $t_issue_id;
}
Expand Down
37 changes: 27 additions & 10 deletions api/soap/mc_project_api.php
Expand Up @@ -23,6 +23,8 @@
* @link http://www.mantisbt.org
*/

use Mantis\Exceptions\ClientException;

/**
* Use a standard filter to get issues associated with the specified user.
*
Expand Down Expand Up @@ -675,13 +677,19 @@ function mci_project_custom_fields_validate( $p_project_id, &$p_custom_fields )
$t_custom_field = ApiObjectFactory::objectToArray( $t_custom_field );

if( !isset( $t_custom_field['value'] ) ) {
$t_error = 'Custom field has no value specified.';
return ApiObjectFactory::faultBadRequest( $t_error );
throw new ClientException(
'Custom field has no value specified.',
ERROR_EMPTY_FIELD,
"custom_field['value']"
);
}

if( !isset( $t_custom_field['field'] ) ) {
$t_error = 'Custom field with no specified id or name.';
return ApiObjectFactory::faultBadRequest( $t_error );
throw new ClientException(
'Custom field with no specified id or name.',
ERROR_EMPTY_FIELD,
"custom_field['field']"
);
}

$t_custom_field['field'] = ApiObjectFactory::objectToArray( $t_custom_field['field'] );
Expand All @@ -698,8 +706,11 @@ function mci_project_custom_fields_validate( $p_project_id, &$p_custom_fields )
continue;
}

$t_error = 'Custom field with no specified id or name.';
return ApiObjectFactory::faultBadRequest( $t_error );
throw new ClientException(
'Custom field with no specified id or name.',
ERROR_EMPTY_FIELD,
"custom_field['field']['id']"
);
}
}

Expand All @@ -717,15 +728,21 @@ function mci_project_custom_fields_validate( $p_project_id, &$p_custom_fields )
if( $t_def['require_report'] ) {
if( !isset( $t_custom_field_values[$t_name] ) ||
is_blank( $t_custom_field_values[$t_name] ) ) {
$t_error = "Mandatory field '$t_name' is missing.";
return ApiObjectFactory::faultBadRequest( $t_error );
throw new ClientException(
"Mandatory field '$t_name' is missing.",
ERROR_EMPTY_FIELD,
array( $t_name )
);
}
}

if( isset( $t_custom_field_values[$t_name] ) &&
!custom_field_validate( $t_custom_field_id, $t_custom_field_values[$t_name] ) ) {
$t_error = "Invalid custom field '$t_name' value.";
return ApiObjectFactory::faultBadRequest( $t_error );
throw new ClientException(
"Invalid custom field '$t_name' value.",
ERROR_EMPTY_FIELD,
array( $t_name )
);
}
}

Expand Down

0 comments on commit 51e1233

Please sign in to comment.