} if (is_blank($t_bug_data->os_build)) { $t_bug_data->os_build = $row['os_build']; } } helper_call_custom_function('issue_create_validate', array($t_bug_data)); # Validate the custom fields before adding the bug. $t_related_custom_field_ids = custom_field_get_linked_ids($t_bug_data->project_id); foreach ($t_related_custom_field_ids as $t_id) { $t_def = custom_field_get_definition($t_id); # Produce an error if the field is required but wasn't posted if (!gpc_isset_custom_field($t_id, $t_def['type']) && $t_def['require_report']) { error_parameters(lang_get_defaulted(custom_field_get_field($t_id, 'name'))); trigger_error(ERROR_EMPTY_FIELD, ERROR); } if (!custom_field_validate($t_id, gpc_get_custom_field("custom_field_{$t_id}", $t_def['type'], NULL))) { error_parameters(lang_get_defaulted(custom_field_get_field($t_id, 'name'))); trigger_error(ERROR_CUSTOM_FIELD_INVALID_VALUE, ERROR); } } # Allow plugins to pre-process bug data $t_bug_data = event_signal('EVENT_REPORT_BUG_DATA', $t_bug_data); # Ensure that resolved bugs have a handler if ($t_bug_data->handler_id == NO_USER && $t_bug_data->status >= config_get('bug_resolved_status_threshold')) { $t_bug_data->handler_id = auth_get_current_user_id(); } # Create the bug $t_bug_id = $t_bug_data->create(); # Mark the added issue as visited so that it appears on the last visited list. last_visited_issue($t_bug_id); # Handle the file upload
/** * Set the value of a custom field for a given bug * return true on success, false on failure * @param integer $p_field_id Custom field identifier. * @param integer $p_bug_id A bug identifier. * @param mixed $p_value New custom field value. * @param boolean $p_log_insert Create history logs for new values. * @return boolean * @access public */ function custom_field_set_value($p_field_id, $p_bug_id, $p_value, $p_log_insert = true) { custom_field_ensure_exists($p_field_id); if (!custom_field_validate($p_field_id, $p_value)) { return false; } $t_name = custom_field_get_field($p_field_id, 'name'); $t_type = custom_field_get_field($p_field_id, 'type'); $t_value_field = $t_type == CUSTOM_FIELD_TYPE_TEXTAREA ? 'text' : 'value'; # Determine whether an existing value needs to be updated or a new value inserted $t_query = 'SELECT ' . $t_value_field . ' FROM {custom_field_string} WHERE field_id=' . db_param() . ' AND bug_id=' . db_param(); $t_result = db_query($t_query, array($p_field_id, $p_bug_id)); if ($t_row = db_fetch_array($t_result)) { $t_query = 'UPDATE {custom_field_string} SET ' . $t_value_field . '=' . db_param() . ' WHERE field_id=' . db_param() . ' AND bug_id=' . db_param(); $t_params = array(custom_field_value_to_database($p_value, $t_type), (int) $p_field_id, (int) $p_bug_id); db_query($t_query, $t_params); history_log_event_direct($p_bug_id, $t_name, custom_field_database_to_value($t_row[$t_value_field], $t_type), $p_value); } else { $t_query = 'INSERT INTO {custom_field_string} ( field_id, bug_id, ' . $t_value_field . ' ) VALUES ( ' . db_param() . ', ' . db_param() . ', ' . db_param() . ')'; $t_params = array((int) $p_field_id, (int) $p_bug_id, custom_field_value_to_database($p_value, $t_type)); db_query($t_query, $t_params); # Don't log history events for new bug reports or on other special occasions if ($p_log_insert) { history_log_event_direct($p_bug_id, $t_name, '', $p_value); } } custom_field_clear_cache($p_field_id); # db_query() errors on failure so: return true; }
/** * Sets the supplied array of custom field values to the specified issue id. * * @param integer $p_issue_id Issue id to apply custom field values to. * @param array &$p_custom_fields The array of custom field values as described in the webservice complex types. * @param boolean $p_log_insert Create history logs for new values. * @return mixed */ function mci_issue_set_custom_fields($p_issue_id, array &$p_custom_fields = null, $p_log_insert) { # set custom field values on the submitted issue if (isset($p_custom_fields) && is_array($p_custom_fields)) { foreach ($p_custom_fields as $t_custom_field) { $t_custom_field = SoapObjectsFactory::unwrapObject($t_custom_field); # Verify validity of custom field specification $t_msg = 'Invalid Custom field specification'; $t_valid_cf = isset($t_custom_field['field']) && isset($t_custom_field['value']); if ($t_valid_cf) { $t_field = get_object_vars($t_custom_field['field']); if ((!isset($t_field['id']) || $t_field['id'] == 0) && !isset($t_field['name'])) { $t_valid_cf = false; $t_msg .= ", either 'name' or 'id' != 0 or must be given."; } } if (!$t_valid_cf) { return SoapObjectsFactory::newSoapFault('Client', $t_msg); } # get custom field id from object ref $t_custom_field_id = mci_get_custom_field_id_from_objectref($t_custom_field['field']); if ($t_custom_field_id == 0) { return SoapObjectsFactory::newSoapFault('Client', "Custom field '" . $t_field['name'] . "' not found."); } # skip if current user doesn't have login access. if (!custom_field_has_write_access($t_custom_field_id, $p_issue_id)) { continue; } $t_value = $t_custom_field['value']; if (!custom_field_validate($t_custom_field_id, $t_value)) { return SoapObjectsFactory::newSoapFault('Client', 'Invalid custom field value for field id ' . $t_custom_field_id . ' .'); } if (!custom_field_set_value($t_custom_field_id, $p_issue_id, $t_value, $p_log_insert)) { return SoapObjectsFactory::newSoapFault('Server', 'Unable to set custom field value for field id ' . $t_custom_field_id . ' to issue ' . $p_issue_id . ' .'); } } } }
# not supply a value. Therefore we can just ignore this # custom field completely (ie. don't attempt to update # the field). continue; } } if (!custom_field_has_write_access($t_cf_id, $f_bug_id)) { trigger_error(ERROR_ACCESS_DENIED, ERROR); } $t_new_custom_field_value = gpc_get_custom_field("custom_field_{$t_cf_id}", $t_cf_def['type'], null); $t_old_custom_field_value = custom_field_get_value($t_cf_id, $f_bug_id); # Validate the value of the field against current validation rules. # This may cause an error if validation rules have recently been # modified such that old values that were once OK are now considered # invalid. if (!custom_field_validate($t_cf_id, $t_new_custom_field_value)) { error_parameters(lang_get_defaulted(custom_field_get_field($t_cf_id, 'name'))); trigger_error(ERROR_CUSTOM_FIELD_INVALID_VALUE, ERROR); } # Remember the new custom field values so we can set them when updating # the bug (done after all data passed to this update page has been # validated). $t_custom_fields_to_set[] = array('id' => $t_cf_id, 'value' => $t_new_custom_field_value); } # Perform validation of the duplicate ID of the bug. if ($t_updated_bug->duplicate_id !== 0) { if ($t_updated_bug->duplicate_id === $f_bug_id) { trigger_error(ERROR_BUG_DUPLICATE_SELF, ERROR); } bug_ensure_exists($t_updated_bug->duplicate_id); if (!access_has_bug_level(config_get('update_bug_threshold'), $t_updated_bug->duplicate_id)) {
} if (is_blank($t_bug_data->os_build)) { $t_bug_data->os_build = $t_row['os_build']; } } helper_call_custom_function('issue_create_validate', array($t_bug_data)); # Validate the custom fields before adding the bug. $t_related_custom_field_ids = custom_field_get_linked_ids($t_bug_data->project_id); foreach ($t_related_custom_field_ids as $t_id) { $t_def = custom_field_get_definition($t_id); # Produce an error if the field is required but wasn't posted if (!gpc_isset_custom_field($t_id, $t_def['type']) && $t_def['require_report']) { error_parameters(lang_get_defaulted(custom_field_get_field($t_id, 'name'))); trigger_error(ERROR_EMPTY_FIELD, ERROR); } if (!custom_field_validate($t_id, gpc_get_custom_field('custom_field_' . $t_id, $t_def['type'], null))) { error_parameters(lang_get_defaulted(custom_field_get_field($t_id, 'name'))); trigger_error(ERROR_CUSTOM_FIELD_INVALID_VALUE, ERROR); } } # Allow plugins to pre-process bug data $t_bug_data = event_signal('EVENT_REPORT_BUG_DATA', $t_bug_data); # Ensure that resolved bugs have a handler if ($t_bug_data->handler_id == NO_USER && $t_bug_data->status >= config_get('bug_resolved_status_threshold')) { $t_bug_data->handler_id = auth_get_current_user_id(); } # Create the bug $t_bug_id = $t_bug_data->create(); $t_bug_data->process_mentions(); # Mark the added issue as visited so that it appears on the last visited list. last_visited_issue($t_bug_id);
/** * Sets the supplied array of custom field values to the specified issue id. * * @param $p_issue_id Issue id to apply custom field values to. * @param $p_custom_fields The array of custom field values as described in the webservice complex types. * @param boolean $p_log_insert create history logs for new values */ function mci_issue_set_custom_fields( $p_issue_id, &$p_custom_fields, $p_log_insert ) { # set custom field values on the submitted issue if( isset( $p_custom_fields ) && is_array( $p_custom_fields ) ) { foreach( $p_custom_fields as $t_custom_field ) { # get custom field id from object ref $t_custom_field_id = mci_get_custom_field_id_from_objectref( $t_custom_field['field'] ); if( $t_custom_field_id == 0 ) { return new soap_fault( 'Client', '', 'Custom field ' . $t_custom_field['field']['name'] . ' not found.' ); } # skip if current user doesn't have login access. if( !custom_field_has_write_access( $t_custom_field_id, $p_issue_id ) ) { continue; } $t_value = $t_custom_field['value']; if( !custom_field_validate( $t_custom_field_id, $t_value ) ) { return new soap_fault( 'Client', '', 'Invalid custom field value for field id ' . $t_custom_field_id . ' .'); } if( !custom_field_set_value( $t_custom_field_id, $p_issue_id, $t_value, $p_log_insert ) ) { return new soap_fault( 'Server', '', 'Unable to set custom field value for field id ' . $t_custom_field_id . ' to issue ' . $p_issue_id. ' .' ); } } } }
$t_bug_data->os = $row['os']; } if (is_blank($t_bug_data->os_build)) { $t_bug_data->os_build = $row['os_build']; } } helper_call_custom_function('issue_create_validate', array($t_bug_data)); # Validate the custom fields before adding the bug. $t_related_custom_field_ids = custom_field_get_linked_ids($t_bug_data->project_id); foreach ($t_related_custom_field_ids as $t_id) { $t_def = custom_field_get_definition($t_id); if ($t_def['require_report'] && gpc_get_custom_field("custom_field_{$t_id}", $t_def['type'], '') == '') { error_parameters(lang_get_defaulted(custom_field_get_field($t_id, 'name'))); trigger_error(ERROR_EMPTY_FIELD, ERROR); } if (!custom_field_validate($t_id, gpc_get_custom_field("custom_field_{$t_id}", $t_def['type'], $t_def['default_value']))) { error_parameters(lang_get_defaulted(custom_field_get_field($t_id, 'name'))); trigger_error(ERROR_CUSTOM_FIELD_INVALID_VALUE, ERROR); } } # Create the bug $t_bug_id = bug_create($t_bug_data); # Handle the file upload if (!is_blank($f_file['tmp_name']) && 0 < $f_file['size']) { $f_file_error = isset($f_file['error']) ? $f_file['error'] : 0; file_add($t_bug_id, $f_file['tmp_name'], $f_file['name'], $f_file['type'], 'bug', $f_file_error); } # Handle custom field submission foreach ($t_related_custom_field_ids as $t_id) { # Do not set custom field value if user has no write access. if (!custom_field_has_write_access($t_id, $t_bug_id)) {
/** * Set the value of a custom field for a given bug * return true on success, false on failure * @param int $p_field_id custom field id * @param int $p_bug_id bug id * @param mixed $p_value * @param boolean $p_log create history logs for new values * @return bool * @access public */ function custom_field_set_value($p_field_id, $p_bug_id, $p_value, $p_log_insert = true) { $c_field_id = db_prepare_int($p_field_id); $c_bug_id = db_prepare_int($p_bug_id); custom_field_ensure_exists($p_field_id); if (!custom_field_validate($p_field_id, $p_value)) { return false; } $t_name = custom_field_get_field($p_field_id, 'name'); $t_type = custom_field_get_field($p_field_id, 'type'); $t_custom_field_string_table = db_get_table('custom_field_string'); $t_value_field = $t_type == CUSTOM_FIELD_TYPE_TEXTAREA ? 'text' : 'value'; # Determine whether an existing value needs to be updated or a new value inserted $query = "SELECT {$t_value_field}\n\t\t\t\t FROM {$t_custom_field_string_table}\n\t\t\t\t WHERE field_id=" . db_param() . " AND\n\t\t\t\t \t\tbug_id=" . db_param(); $result = db_query_bound($query, array($c_field_id, $c_bug_id)); if (db_num_rows($result) > 0) { $query = "UPDATE {$t_custom_field_string_table}\n\t\t\t\t\t SET {$t_value_field}=" . db_param() . "\n\t\t\t\t\t WHERE field_id=" . db_param() . " AND\n\t\t\t\t\t \t\tbug_id=" . db_param(); db_query_bound($query, array(custom_field_value_to_database($p_value, $t_type), $c_field_id, $c_bug_id)); $row = db_fetch_array($result); history_log_event_direct($c_bug_id, $t_name, custom_field_database_to_value($row[$t_value_field], $t_type), $p_value); } else { $query = "INSERT INTO {$t_custom_field_string_table}\n\t\t\t\t\t\t( field_id, bug_id, {$t_value_field} )\n\t\t\t\t\t VALUES\n\t\t\t\t\t\t( " . db_param() . ', ' . db_param() . ', ' . db_param() . ')'; db_query_bound($query, array($c_field_id, $c_bug_id, custom_field_value_to_database($p_value, $t_type))); # Don't log history events for new bug reports or on other special occasions if ($p_log_insert) { history_log_event_direct($c_bug_id, $t_name, '', $p_value); } } custom_field_clear_cache($p_field_id); # db_query errors on failure so: return true; }
continue; } # Do not set custom field value if user has no write access. if (!custom_field_has_write_access($t_id, $f_bug_id)) { continue; } # Produce an error if the field is required but wasn't posted if (!gpc_isset_custom_field($t_id, $t_def['type']) && $t_def['require_' . $t_custom_status_label]) { error_parameters(lang_get_defaulted(custom_field_get_field($t_id, 'name'))); trigger_error(ERROR_EMPTY_FIELD, ERROR); } $t_new_custom_field_value = gpc_get_custom_field("custom_field_{$t_id}", $t_def['type'], ''); $t_old_custom_field_value = custom_field_get_value($t_id, $f_bug_id); # Don't update the custom field if the new value both matches the old value and is valid # This ensures that changes to custom field validation will force the update of old invalid custom field values if ($t_new_custom_field_value === $t_old_custom_field_value && custom_field_validate($t_id, $t_new_custom_field_value)) { continue; } # Attempt to set the new custom field value if (!custom_field_set_value($t_id, $f_bug_id, $t_new_custom_field_value)) { error_parameters(lang_get_defaulted(custom_field_get_field($t_id, 'name'))); trigger_error(ERROR_CUSTOM_FIELD_INVALID_VALUE, ERROR); } } $t_notify = true; $t_bug_note_set = false; if ($t_old_bug_status != $t_bug_data->status && FALSE == $f_update_mode) { # handle status transitions that come from pages other than bug_*update_page.php # this does the minimum to act on the bug and sends a specific message if ($t_bug_data->status >= $t_resolved && $t_bug_data->status < $t_closed && $t_old_bug_status < $t_resolved) { # bug_resolve updates the status, fixed_in_version, resolution,
function save_bug($p_project_id, $p_user_id) { require 'ProfileAcraExt.php'; $t_project_id = $p_project_id; global $g_cache_current_user_id; $g_cache_current_user_id = $p_user_id; $t_bug_data = new BugData(); $t_bug_data->project_id = $t_project_id; $t_bug_data->reporter_id = $p_user_id; $t_bug_data->build = gpc_get_string('APP_VERSION_CODE', ''); $t_bug_data->platform = "Android"; $t_bug_data->os = gpc_get_string('ANDROID_VERSION', ''); //gpc_get_string( 'os', '' ); $t_os_build = gpc_get_string('BUILD', ''); if (preg_match('/DISPLAY\\s*=\\s*(.*)/', $t_os_build, $t_match)) { var_dump($t_match); $t_os_build = $t_match[1]; } else { $t_os_build = gpc_get_string('ANDROID_VERSION', ''); } $t_bug_data->os_build = $t_os_build; //gpc_get_string( 'os_build', '' ); $t_bug_data->version = gpc_get_string('APP_VERSION_NAME', ''); $t_bug_data->profile_id = profile_create_unique(ALL_USERS, $t_bug_data->platform, $t_bug_data->os, $t_bug_data->os_build, ""); $t_bug_data->handler_id = gpc_get_int('handler_id', 0); $t_bug_data->view_state = gpc_get_int('view_state', config_get('default_bug_view_status', 'VS_PRIVATE', 'acra_reporter')); $t_bug_data->category_id = $this->get_category_id($p_project_id); //gpc_get_int( 'category_id', 0 ); $t_bug_data->reproducibility = 10; //gpc_get_int( 'reproducibility', config_get( 'default_bug_reproducibility' ) ); $t_bug_data->severity = CRASH; //gpc_get_int( 'severity', config_get( 'default_bug_severity' ) ); $t_bug_data->priority = HIGH; //gpc_get_int( 'priority', config_get( 'default_bug_priority' ) ); $t_bug_data->projection = gpc_get_int('projection', config_get('default_bug_projection')); $t_bug_data->eta = gpc_get_int('eta', config_get('default_bug_eta')); $t_bug_data->resolution = OPEN; //gpc_get_string('resolution', config_get( 'default_bug_resolution' ) ); $t_bug_data->status = NEW_; //gpc_get_string( 'status', config_get( 'bug_submit_status' ) ); $t_bug_data->description = gpc_get_string('STACK_TRACE'); //gpc_get_string( 'description' ); $t_bug_data->summary = get_bug_summary_by_version(gpc_get_string('APP_VERSION_NAME', ''), $t_bug_data->description, $t_project_id); $t_bug_data->steps_to_reproduce = gpc_get_string('LOGCAT', ""); $t_bug_data->additional_information = gpc_get_string('CRASH_CONFIGURATION', ""); $t_bug_data->due_date = gpc_get_string('USER_CRASH_DATE', ''); if (is_blank($t_bug_data->due_date)) { $t_bug_data->due_date = date_get_null(); } $f_files = gpc_get_file('ufile', null); /** @todo (thraxisp) Note that this always returns a structure */ $f_report_stay = gpc_get_bool('report_stay', false); $f_copy_notes_from_parent = gpc_get_bool('copy_notes_from_parent', false); helper_call_custom_function('issue_create_validate', array($t_bug_data)); # Validate the custom fields before adding the bug. $t_related_custom_field_ids = custom_field_get_linked_ids($t_bug_data->project_id); foreach ($t_related_custom_field_ids as $t_id) { $t_def = custom_field_get_definition($t_id); # Produce an error if the field is required but wasn't posted if (!gpc_isset_custom_field($t_id, $t_def['type']) && $t_def['require_report']) { error_parameters(lang_get_defaulted(custom_field_get_field($t_id, 'name'))); trigger_error(ERROR_EMPTY_FIELD, ERROR); } if (!custom_field_validate($t_id, gpc_get_custom_field("custom_field_{$t_id}", $t_def['type'], NULL))) { error_parameters(lang_get_defaulted(custom_field_get_field($t_id, 'name'))); trigger_error(ERROR_CUSTOM_FIELD_INVALID_VALUE, ERROR); } } # Allow plugins to pre-process bug data $t_bug_data = event_signal('EVENT_REPORT_BUG_DATA', $t_bug_data); # Ensure that resolved bugs have a handler if ($t_bug_data->handler_id == NO_USER && $t_bug_data->status >= config_get('bug_resolved_status_threshold')) { $t_bug_data->handler_id = $this->get_user_id(); } # Create the bug $t_bug_id = $t_bug_data->create(); # Mark the added issue as visited so that it appears on the last visited list. last_visited_issue($t_bug_id); # Handle the file upload if ($f_files != null) { $t_files = helper_array_transpose($f_files); if ($t_files != null) { foreach ($t_files as $t_file) { if (!empty($t_file['name'])) { file_add($t_bug_id, $t_file, 'bug'); } } } } # Handle custom field submission foreach ($t_related_custom_field_ids as $t_id) { # Do not set custom field value if user has no write access if (!custom_field_has_write_access($t_id, $t_bug_id)) { continue; } $t_def = custom_field_get_definition($t_id); if (!custom_field_set_value($t_id, $t_bug_id, gpc_get_custom_field("custom_field_{$t_id}", $t_def['type'], $t_def['default_value']), false)) { error_parameters(lang_get_defaulted(custom_field_get_field($t_id, 'name'))); trigger_error(ERROR_CUSTOM_FIELD_INVALID_VALUE, ERROR); } } $f_master_bug_id = gpc_get_int('m_id', 0); $f_rel_type = gpc_get_int('rel_type', -1); if ($f_master_bug_id > 0) { # it's a child generation... let's create the relationship and add some lines in the history # update master bug last updated bug_update_date($f_master_bug_id); # Add log line to record the cloning action history_log_event_special($t_bug_id, BUG_CREATED_FROM, '', $f_master_bug_id); history_log_event_special($f_master_bug_id, BUG_CLONED_TO, '', $t_bug_id); if ($f_rel_type >= 0) { # Add the relationship relationship_add($t_bug_id, $f_master_bug_id, $f_rel_type); # Add log line to the history (both issues) history_log_event_special($f_master_bug_id, BUG_ADD_RELATIONSHIP, relationship_get_complementary_type($f_rel_type), $t_bug_id); history_log_event_special($t_bug_id, BUG_ADD_RELATIONSHIP, $f_rel_type, $f_master_bug_id); # update relationship target bug last updated bug_update_date($t_bug_id); # Send the email notification email_relationship_added($f_master_bug_id, $t_bug_id, relationship_get_complementary_type($f_rel_type)); } # copy notes from parent if ($f_copy_notes_from_parent) { $t_parent_bugnotes = bugnote_get_all_bugnotes($f_master_bug_id); foreach ($t_parent_bugnotes as $t_parent_bugnote) { $t_private = $t_parent_bugnote->view_state == VS_PRIVATE; bugnote_add($t_bug_id, $t_parent_bugnote->note, $t_parent_bugnote->time_tracking, $t_private, $t_parent_bugnote->note_type, $t_parent_bugnote->note_attr, $t_parent_bugnote->reporter_id, FALSE, FALSE); } } } helper_call_custom_function('issue_create_notify', array($t_bug_id)); # Allow plugins to post-process bug data with the new bug ID event_signal('EVENT_REPORT_BUG', array($t_bug_data, $t_bug_id)); email_new_bug($t_bug_id); // log status and resolution changes if they differ from the default if ($t_bug_data->status != config_get('bug_submit_status')) { history_log_event($t_bug_id, 'status', config_get('bug_submit_status')); } if ($t_bug_data->resolution != config_get('default_bug_resolution')) { history_log_event($t_bug_id, 'resolution', config_get('default_bug_resolution')); } return $t_bug_id; }