public function process(XMLreader $reader) { //print "\nImportIssue process()\n"; $t_project_id = helper_get_current_project(); // TODO: category_get_id_by_name could work by default on current project $userId = auth_get_current_user_id(); $t_custom_fields = array(); $t_bugnotes = array(); $t_attachments = array(); $depth = $reader->depth; while ($reader->read() && ($reader->depth > $depth || $reader->nodeType != XMLReader::END_ELEMENT)) { if ($reader->nodeType == XMLReader::ELEMENT) { switch ($reader->localName) { case 'reporter': $t_old_id = $reader->getAttribute('id'); $reader->read(); $this->newbug_->reporter_id = $this->get_user_id($reader->value, $userId); //echo "reporter: old id = $t_old_id - new id = {$this->newbug_->reporter_id}\n"; break; case 'handler': $t_old_id = $reader->getAttribute('id'); $reader->read(); $this->newbug_->handler_id = $this->get_user_id($reader->value, $userId); //echo "handler: old id = $t_old_id - new id = {$this->newbug_->handler_id}\n"; break; case 'category': $this->newbug_->category_id = $this->defaultCategory_; if (version_compare(MANTIS_VERSION, '1.2', '>') === true) { $reader->read(); if ($this->keepCategory_) { # Check for the category's existence in the current project # well as its parents (if any) $t_projects_hierarchy = project_hierarchy_inheritance($t_project_id); foreach ($t_projects_hierarchy as $t_project) { $t_category_id = category_get_id_by_name($reader->value, $t_project, false); if ($t_category_id !== false) { $this->newbug_->category_id = $t_category_id; break; } } } // echo "new id = {$this->newbug_->category_id}\n"; } break; case 'eta': case 'priority': case 'projection': case 'reproducibility': case 'resolution': case 'severity': case 'status': case 'view_state': $t_field = $reader->localName; $t_id = $reader->getAttribute('id'); $reader->read(); $t_value = $reader->value; // Here we assume ids have the same meaning in both installations // TODO add a check for customized values $this->newbug_->{$t_field} = $t_id; break; case 'id': $reader->read(); $this->old_id_ = $reader->value; break; case 'project': // ignore original value, use current project $this->newbug_->project_id = $t_project_id; break; case 'custom_fields': // store custom fields $i = -1; $depth_cf = $reader->depth; while ($reader->read() && ($reader->depth > $depth_cf || $reader->nodeType != XMLReader::END_ELEMENT)) { if ($reader->nodeType == XMLReader::ELEMENT) { if ($reader->localName == 'custom_field') { $t_custom_fields[++$i] = new stdClass(); } switch ($reader->localName) { default: $field = $reader->localName; $reader->read(); $t_custom_fields[$i]->{$field} = $reader->value; } } } break; case 'bugnotes': // store bug notes $i = -1; $depth_bn = $reader->depth; while ($reader->read() && ($reader->depth > $depth_bn || $reader->nodeType != XMLReader::END_ELEMENT)) { if ($reader->nodeType == XMLReader::ELEMENT) { if ($reader->localName == 'bugnote') { $t_bugnotes[++$i] = new stdClass(); } switch ($reader->localName) { case 'reporter': $t_old_id = $reader->getAttribute('id'); $reader->read(); $t_bugnotes[$i]->reporter_id = $this->get_user_id($reader->value, $userId); break; case 'view_state': $t_old_id = $reader->getAttribute('id'); $reader->read(); $t_bugnotes[$i]->private = $reader->value == VS_PRIVATE ? true : false; break; default: $field = $reader->localName; $reader->read(); $t_bugnotes[$i]->{$field} = $reader->value; } } } break; case 'attachments': // store attachments $i = -1; $depth_att = $reader->depth; while ($reader->read() && ($reader->depth > $depth_att || $reader->nodeType != XMLReader::END_ELEMENT)) { if ($reader->nodeType == XMLReader::ELEMENT) { if ($reader->localName == 'attachment') { $t_attachments[++$i] = new stdClass(); } switch ($reader->localName) { default: $field = $reader->localName; $reader->read(); $t_attachments[$i]->{$field} = $reader->value; } } } break; default: $field = $reader->localName; //echo "using default handler for field: $field\n"; $reader->read(); $this->newbug_->{$field} = $reader->value; } } } // now save the new bug $this->new_id_ = $this->newbug_->create(); // add custom fields if ($this->new_id_ > 0 && is_array($t_custom_fields) && count($t_custom_fields) > 0) { foreach ($t_custom_fields as $t_custom_field) { $t_custom_field_id = custom_field_get_id_from_name($t_custom_field->name); if (custom_field_ensure_exists($t_custom_field_id) && custom_field_is_linked($t_custom_field_id, $t_project_id)) { custom_field_set_value($t_custom_field->id, $this->new_id_, $t_custom_field->value); } else { error_parameters($t_custom_field->name, $t_custom_field_id); trigger_error(ERROR_CUSTOM_FIELD_NOT_LINKED_TO_PROJECT, ERROR); } } } // add bugnotes if ($this->new_id_ > 0 && is_array($t_bugnotes) && count($t_bugnotes) > 0) { foreach ($t_bugnotes as $t_bugnote) { bugnote_add($this->new_id_, $t_bugnote->note, $t_bugnote->time_tracking, $t_bugnote->private, $t_bugnote->note_type, $t_bugnote->note_attr, $t_bugnote->reporter_id, false, $t_bugnote->date_submitted, $t_bugnote->last_modified, true); } } // add attachments if ($this->new_id_ > 0 && is_array($t_attachments) && count($t_attachments) > 0) { foreach ($t_attachments as $t_attachment) { // Create a temporary file in the temporary files directory using sys_get_temp_dir() $temp_file_name = tempnam(sys_get_temp_dir(), 'MantisImport'); file_put_contents($temp_file_name, base64_decode($t_attachment->content)); $file_data = array('name' => $t_attachment->filename, 'type' => $t_attachment->file_type, 'tmp_name' => $temp_file_name, 'size' => filesize($temp_file_name), 'error' => UPLOAD_ERR_OK); // unfortunately we have no clue who has added the attachment (this could only be fetched from history -> feel free to implement this) // also I have no clue where description should come from... file_add($this->new_id_, $file_data, 'bug', $t_attachment->title, $p_desc = '', $p_user_id = null, $t_attachment->date_added, true); unlink($temp_file_name); } } //echo "\nnew bug: $this->new_id_\n"; }
$t_file['name'] = $f_files['name'][$i]; $t_file['tmp_name'] = $f_files['tmp_name'][$i]; $t_file['type'] = $f_files['type'][$i]; $t_file['error'] = $f_files['error'][$i]; $t_file['size'] = $f_files['size'][$i]; 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
# The new value is the inverted old value # @todo we need to issue a helper_call_custom_function( 'issue_update_validate', array( $t_bug_id, $t_bug_data, $f_bugnote_text ) ); bug_set_field($t_bug_id, 'sticky', intval(!$f_sticky)); helper_call_custom_function('issue_update_notify', array($t_bug_id)); } else { $t_failed_ids[$t_bug_id] = lang_get('bug_actiongroup_access'); } break; case 'CUSTOM': if (0 === $f_custom_field_id) { trigger_error(ERROR_GENERIC, ERROR); } # @todo we need to issue a helper_call_custom_function( 'issue_update_validate', array( $t_bug_id, $t_bug_data, $f_bugnote_text ) ); $t_form_var = 'custom_field_' . $f_custom_field_id; $t_custom_field_value = gpc_get_custom_field($t_form_var, $t_custom_field_def['type'], null); custom_field_set_value($f_custom_field_id, $t_bug_id, $t_custom_field_value); bug_update_date($t_bug_id); email_bug_updated($t_bug_id); helper_call_custom_function('issue_update_notify', array($t_bug_id)); break; default: trigger_error(ERROR_GENERIC, ERROR); } # Bug Action Event event_signal('EVENT_BUG_ACTION', array($f_action, $t_bug_id)); } form_security_purge($t_form_name); $t_redirect_url = 'view_all_bug_page.php'; if (count($t_failed_ids) > 0) { html_page_top(); echo '<div><br />';
/** * 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 . ' .'); } } } }
if (!(!$f_update_mode && $t_def['require_' . $t_custom_status_label] || !$f_update_mode && $t_def['display_' . $t_custom_status_label] && in_array($t_custom_status_label, array("resolved", "closed")) || $f_update_mode && $t_def['display_update'] || $f_update_mode && $t_def['require_update'])) { 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; } if ($t_def['require_' . $t_custom_status_label] && !gpc_isset("custom_field_{$t_id}")) { error_parameters(lang_get_defaulted(custom_field_get_field($t_id, 'name'))); trigger_error(ERROR_EMPTY_FIELD, ERROR); } # Only update the field if it is posted if (!gpc_isset("custom_field_{$t_id}")) { continue; } if (!custom_field_set_value($t_id, $f_bug_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); } } $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 switch ($t_bug_data->status) { case $t_resolved: # bug_resolve updates the status, fixed_in_version, resolution, handler_id and bugnote and sends message bug_resolve($f_bug_id, $t_bug_data->resolution, $t_bug_data->fixed_in_version, $f_bugnote_text, $t_bug_data->duplicate_id, $t_bug_data->handler_id, $f_private, $f_time_tracking); $t_notify = false; $t_bug_note_set = true;
/** * 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. ' .' ); } } } }
# Handle automatic assignment of issues. if ($t_existing_bug->handler_id === NO_USER && $t_updated_bug->handler_id !== NO_USER && $t_updated_bug->status < config_get('bug_assigned_status') && config_get('auto_set_status_to_assigned')) { $t_updated_bug->status = config_get('bug_assigned_status'); } # Allow a custom function to validate the proposed bug updates. Note that # custom functions are being deprecated in MantisBT. You should migrate to # the new plugin system instead. helper_call_custom_function('issue_update_validate', array($f_bug_id, $t_updated_bug, $t_bug_note->note)); # Allow plugins to validate/modify the update prior to it being committed. $t_updated_bug = event_signal('EVENT_UPDATE_BUG_DATA', $t_updated_bug, $t_existing_bug); # Commit the bug updates to the database. $t_text_field_update_required = $t_existing_bug->description !== $t_updated_bug->description || $t_existing_bug->additional_information !== $t_updated_bug->additional_information || $t_existing_bug->steps_to_reproduce !== $t_updated_bug->steps_to_reproduce; $t_updated_bug->update($t_text_field_update_required, true); # Update custom field values. foreach ($t_custom_fields_to_set as $t_custom_field_to_set) { custom_field_set_value($t_custom_field_to_set['id'], $f_bug_id, $t_custom_field_to_set['value']); } # Add a bug note if there is one. if ($t_bug_note->note || helper_duration_to_minutes($t_bug_note->time_tracking) > 0) { bugnote_add($f_bug_id, $t_bug_note->note, $t_bug_note->time_tracking, $t_bug_note->view_state == VS_PRIVATE, 0, '', null, false); } # Add a duplicate relationship if requested. if ($t_updated_bug->duplicate_id !== 0) { relationship_add($f_bug_id, $t_updated_bug->duplicate_id, BUG_DUPLICATE); history_log_event_special($f_bug_id, BUG_ADD_RELATIONSHIP, BUG_DUPLICATE, $t_updated_bug->duplicate_id); history_log_event_special($t_updated_bug->duplicate_id, BUG_ADD_RELATIONSHIP, BUG_HAS_DUPLICATE, $f_bug_id); if (user_exists($t_existing_bug->reporter_id)) { bug_monitor($f_bug_id, $t_existing_bug->reporter_id); } if (user_exists($t_existing_bug->handler_id)) { bug_monitor($f_bug_id, $t_existing_bug->handler_id);
continue; } # Only update the field if it is posted # ( will fail in custom_field_set_value(), if it was required ) if ($t_custom_field_value === null) { 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; } if ($t_def['require_' . $t_custom_status_label] && 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_set_value($t_id, $f_bug_id, $t_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 switch ($t_bug_data->status) { case $t_resolved: # bug_resolve updates the status, fixed_in_version, resolution, handler_id and bugnote and sends message bug_resolve($f_bug_id, $t_bug_data->resolution, $t_bug_data->fixed_in_version, $f_bugnote_text, $t_bug_data->duplicate_id, $t_bug_data->handler_id, $f_private, $f_time_tracking); $t_notify = false; $t_bug_note_set = true;
function restoreCustomFieldValue($p_bug_id, $p_field_id, $p_value) { custom_field_set_value($p_field_id, $p_bug_id, $p_value); }
/** * updates the status field * @return bool * @access public * @see bug_update.php */ function kanban_ajax_request_bug_update_status() { $p_bug_id = gpc_get_int('id'); $p_new_status = gpc_get_int('new_status'); $t_project_id = gpc_get_int('project_id'); $c_bug_id = (int) $p_bug_id; $f_new_status = (int) $p_new_status; $t_bug_data = bug_get($c_bug_id, true); $f_update_mode = gpc_get_bool('update_mode', FALSE); # set if called from generic update page if (!(access_has_bug_level(access_get_status_threshold($f_new_status, $t_project_id), $c_bug_id) || access_has_bug_level(config_get('update_bug_threshold'), $c_bug_id) || bug_get_field($c_bug_id, 'reporter_id') == auth_get_current_user_id() && (ON == config_get('allow_reporter_reopen') || ON == config_get('allow_reporter_close')))) { access_denied(); } # extract current extended information $t_old_bug_status = $t_bug_data->status; log_event(LOG_AJAX, "Old bug status {$t_old_bug_status} - trying update to new status {$f_new_status}..."); $t_bug_data->reporter_id = gpc_get_int('reporter_id', $t_bug_data->reporter_id); $t_bug_data->handler_id = gpc_get_int('handler_id', $t_bug_data->handler_id); $t_bug_data->duplicate_id = gpc_get_int('duplicate_id', $t_bug_data->duplicate_id); $t_bug_data->priority = gpc_get_int('priority', $t_bug_data->priority); $t_bug_data->severity = gpc_get_int('severity', $t_bug_data->severity); $t_bug_data->reproducibility = gpc_get_int('reproducibility', $t_bug_data->reproducibility); $t_bug_data->status = gpc_get_int('new_status', $t_bug_data->status); $t_bug_data->resolution = gpc_get_int('resolution', $t_bug_data->resolution); $t_bug_data->projection = gpc_get_int('projection', $t_bug_data->projection); $t_bug_data->category_id = gpc_get_int('category_id', $t_bug_data->category_id); $t_bug_data->eta = gpc_get_int('eta', $t_bug_data->eta); $t_bug_data->os = gpc_get_string('os', $t_bug_data->os); $t_bug_data->os_build = gpc_get_string('os_build', $t_bug_data->os_build); $t_bug_data->platform = gpc_get_string('platform', $t_bug_data->platform); $t_bug_data->version = gpc_get_string('version', $t_bug_data->version); $t_bug_data->build = gpc_get_string('build', $t_bug_data->build); $t_bug_data->fixed_in_version = gpc_get_string('fixed_in_version', $t_bug_data->fixed_in_version); $t_bug_data->view_state = gpc_get_int('view_state', $t_bug_data->view_state); $t_bug_data->summary = gpc_get_string('summary', $t_bug_data->summary); $t_due_date = gpc_get_string('due_date', null); if (access_has_project_level(config_get('roadmap_update_threshold'), $t_bug_data->project_id)) { $t_bug_data->target_version = gpc_get_string('target_version', $t_bug_data->target_version); } if ($t_due_date !== null) { if (is_blank($t_due_date)) { $t_bug_data->due_date = 1; } else { $t_bug_data->due_date = strtotime($t_due_date); } } $t_bug_data->description = gpc_get_string('description', $t_bug_data->description); $t_bug_data->steps_to_reproduce = gpc_get_string('steps_to_reproduce', $t_bug_data->steps_to_reproduce); $t_bug_data->additional_information = gpc_get_string('additional_information', $t_bug_data->additional_information); $f_private = gpc_get_bool('private'); $f_bugnote_text = gpc_get_string('bugnote_text', ''); $f_time_tracking = gpc_get_string('time_tracking', '0:00'); $f_close_now = gpc_get_string('close_now', false); # Handle auto-assigning if (config_get('bug_submit_status') == $t_bug_data->status && $t_bug_data->status == $t_old_bug_status && 0 != $t_bug_data->handler_id && ON == config_get('auto_set_status_to_assigned')) { $t_bug_data->status = config_get('bug_assigned_status'); } helper_call_custom_function('issue_update_validate', array($c_bug_id, $t_bug_data, $f_bugnote_text)); $t_resolved = config_get('bug_resolved_status_threshold'); $t_closed = config_get('bug_closed_status_threshold'); $t_custom_status_label = "update"; # default info to check if ($t_bug_data->status == $t_resolved) { $t_custom_status_label = "resolved"; } if ($t_bug_data->status == $t_closed) { $t_custom_status_label = "closed"; } $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); # Only update the field if it would have been display for editing if (!(!$f_update_mode && $t_def['require_' . $t_custom_status_label] || !$f_update_mode && $t_def['display_' . $t_custom_status_label] && in_array($t_custom_status_label, array("resolved", "closed")) || $f_update_mode && $t_def['display_update'] || $f_update_mode && $t_def['require_update'])) { continue; } # Do not set custom field value if user has no write access. if (!custom_field_has_write_access($t_id, $c_bug_id)) { continue; } if ($t_def['require_' . $t_custom_status_label] && !gpc_isset_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); } # Only update the field if it is posted, # or if it is empty, and the current value isn't the default if (!gpc_isset_custom_field($t_id, $t_def['type']) && custom_field_get_value($t_id, $c_bug_id) == $t_def['default_value']) { continue; } if (!custom_field_set_value($t_id, $c_bug_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'))); log_event(LOG_AJAX, "Error setting new status: " . ERROR_CUSTOM_FIELD_INVALID_VALUE . "\nBugdata: " . print_r($t_bug_data, true) . " Line: " . __LINE__); 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, handler_id and bugnote and sends message bug_resolve($c_bug_id, $t_bug_data->resolution, $t_bug_data->fixed_in_version, $f_bugnote_text, $t_bug_data->duplicate_id, $t_bug_data->handler_id, $f_private, $f_time_tracking); $t_notify = false; $t_bug_note_set = true; if ($f_close_now) { bug_set_field($c_bug_id, 'status', $t_closed); } // update bug data with fields that may be updated inside bug_resolve(), otherwise changes will be overwritten // in bug_update() call below. $t_bug_data->handler_id = bug_get_field($c_bug_id, 'handler_id'); $t_bug_data->status = bug_get_field($c_bug_id, 'status'); } else { if ($t_bug_data->status >= $t_closed && $t_old_bug_status < $t_closed) { # bug_close updates the status and bugnote and sends message bug_close($c_bug_id, $f_bugnote_text, $f_private, $f_time_tracking); $t_notify = false; $t_bug_note_set = true; } else { if ($t_bug_data->status == config_get('bug_reopen_status') && $t_old_bug_status >= $t_resolved) { bug_set_field($c_bug_id, 'handler_id', $t_bug_data->handler_id); # fix: update handler_id before calling bug_reopen # bug_reopen updates the status and bugnote and sends message bug_reopen($c_bug_id, $f_bugnote_text, $f_time_tracking, $f_private); $t_notify = false; $t_bug_note_set = true; // update bug data with fields that may be updated inside bug_resolve(), otherwise changes will be overwritten // in bug_update() call below. $t_bug_data->status = bug_get_field($c_bug_id, 'status'); $t_bug_data->resolution = bug_get_field($c_bug_id, 'resolution'); } } } } # Plugin support $t_new_bug_data = event_signal('EVENT_UPDATE_BUG', $t_bug_data, $c_bug_id); if (!is_null($t_new_bug_data)) { $t_bug_data = $t_new_bug_data; } # Add a bugnote if there is one if (false == $t_bug_note_set) { bugnote_add($c_bug_id, $f_bugnote_text, $f_time_tracking, $f_private, 0, '', NULL, FALSE); } # Update the bug entry, notify if we haven't done so already $t_bug_data->update(true, false == $t_notify); helper_call_custom_function('issue_update_notify', array($c_bug_id)); return true; }
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; }
last_visited_issue( $t_bug_id ); # Handle the file upload if ( !is_blank( $f_file['tmp_name'] ) && ( 0 < $f_file['size'] ) ) { file_add( $t_bug_id, $f_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'], '' ), 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