/** * Executes the custom action on the specified bug id. * * @param $p_bug_id The bug id to execute the custom action on. * @returns true|array Action executed successfully., ( bug_id => reason for failure ) */ function action_update_product_build_process($p_bug_id) { $f_build = gpc_get_string('build'); $t_build = trim($f_build); bug_set_field($p_bug_id, 'build', $t_build); return true; }
function custom_function_default_checkin($p_issue_id, $p_comment, $p_file, $p_new_version, $p_fixed) { if (bug_exists($p_issue_id)) { history_log_event_special($p_issue_id, CHECKIN, $p_file, $p_new_version); bugnote_add($p_issue_id, $p_comment, VS_PRIVATE == config_get('source_control_notes_view_status')); $t_status = config_get('source_control_set_status_to'); if (OFF != $t_status && $p_fixed) { bug_set_field($p_issue_id, 'status', $t_status); bug_set_field($p_issue_id, 'resolution', config_get('source_control_set_resolution_to')); } } }
if (access_has_bug_level(config_get('change_view_status_threshold'), $t_bug_id)) { $f_view_status = gpc_get_int('view_status'); # @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, 'view_state', $f_view_status); email_bug_updated($t_bug_id); 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 'SET_STICKY': if (access_has_bug_level(config_get('set_bug_sticky_threshold'), $t_bug_id)) { $f_sticky = bug_get_field($t_bug_id, 'sticky'); # 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);
/** * Executes the custom action on the specified bug id. * * @param $p_bug_id The bug id to execute the custom action on. * * @return null Previous validation ensures that this function doesn't fail. Therefore we can always return null to indicate no errors occurred. */ function action_update_severity_process($p_bug_id) { $f_severity = gpc_get_string('severity'); bug_set_field($p_bug_id, 'severity', $f_severity); return null; }
extract($row, EXTR_PREFIX_ALL, 'v'); # trace bug id back to project $t_project_id = bug_get_field($v_bug_id, 'project_id'); $t_cust_value = $v_value; printf("\n<tr %s><td><a href=\"../view.php?id=%d\">%07d</a></td><td>%s</td><td>", helper_alternate_class(), $v_bug_id, $v_bug_id, $v_value); # validate field contents switch ($f_dest_field) { case 'fixed_in_version': $t_valid = version_get_id($t_cust_value, $t_project_id) == FALSE ? FALSE : TRUE; break; default: $t_valid = FALSE; } if ($t_valid) { # value was valid, update value if (!bug_set_field($v_bug_id, $f_dest_field, $t_cust_value)) { echo 'database update failed'; $t_failures++; } else { echo 'applied'; } } else { echo 'field value was not valid or previously defined'; $t_failures++; } echo '</td></tr>'; } echo '</table><br />' . $count . ' fields processed, ' . $t_failures . ' failures'; } echo '<p> Completed...<p>'; ?>
/** * Add a bugnote to a bug * return the ID of the new bugnote * @param int $p_bug_id bug id * @param string $p_bugnote_text bugnote text * @param string $p_time_tracking hh:mm string * @param bool $p_private whether bugnote is private * @param int $p_type bugnote type * @param string $p_attr * @param int $p_user_id user id * @param bool $p_send_email generate email? * @return false|int false or indicating bugnote id added * @access public */ function bugnote_add($p_bug_id, $p_bugnote_text, $p_time_tracking = '0:00', $p_private = false, $p_type = BUGNOTE, $p_attr = '', $p_user_id = null, $p_send_email = TRUE, $p_log_history = TRUE) { $c_bug_id = db_prepare_int($p_bug_id); $c_time_tracking = helper_duration_to_minutes($p_time_tracking); $c_type = db_prepare_int($p_type); if (REMINDER !== $p_type) { # Check if this is a time-tracking note $t_time_tracking_enabled = config_get('time_tracking_enabled'); if (ON == $t_time_tracking_enabled && $c_time_tracking > 0) { $t_time_tracking_without_note = config_get('time_tracking_without_note'); if (is_blank($p_bugnote_text) && OFF == $t_time_tracking_without_note) { error_parameters(lang_get('bugnote')); trigger_error(ERROR_EMPTY_FIELD, ERROR); } $c_type = TIME_TRACKING; } else { if (is_blank($p_bugnote_text)) { # This is not time tracking (i.e. it's a normal bugnote) # @todo should we not trigger an error in this case ? return false; } } } $t_bugnote_text_table = db_get_table('mantis_bugnote_text_table'); $t_bugnote_table = db_get_table('mantis_bugnote_table'); # Event integration $t_bugnote_text = event_signal('EVENT_BUGNOTE_DATA', $p_bugnote_text, $c_bug_id); # insert bugnote text $query = 'INSERT INTO ' . $t_bugnote_text_table . ' ( note ) VALUES ( ' . db_param() . ' )'; db_query_bound($query, array($t_bugnote_text)); # retrieve bugnote text id number $t_bugnote_text_id = db_insert_id($t_bugnote_text_table); # get user information if ($p_user_id === null) { $c_user_id = auth_get_current_user_id(); } else { $c_user_id = db_prepare_int($p_user_id); } # Check for private bugnotes. # @@@ VB: Should we allow users to report private bugnotes, and possibly see only their own private ones if ($p_private && access_has_bug_level(config_get('private_bugnote_threshold'), $p_bug_id, $c_user_id)) { $t_view_state = VS_PRIVATE; } else { $t_view_state = VS_PUBLIC; } # insert bugnote info $query = "INSERT INTO {$t_bugnote_table}\n\t\t\t\t(bug_id, reporter_id, bugnote_text_id, view_state, date_submitted, last_modified, note_type, note_attr, time_tracking )\n\t\t\tVALUES\n\t\t\t\t(" . db_param() . ', ' . db_param() . ',' . db_param() . ', ' . db_param() . ', ' . db_param() . ',' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ' )'; db_query_bound($query, array($c_bug_id, $c_user_id, $t_bugnote_text_id, $t_view_state, db_now(), db_now(), $c_type, $p_attr, $c_time_tracking)); # get bugnote id $t_bugnote_id = db_insert_id($t_bugnote_table); # update bug last updated bug_update_date($p_bug_id); # log new bug if (TRUE == $p_log_history) { history_log_event_special($p_bug_id, BUGNOTE_ADDED, bugnote_format_id($t_bugnote_id)); } # if it was FEEDBACK its NEW_ now if (config_get('reassign_on_feedback') && bug_get_field($p_bug_id, 'status') == config_get('bug_feedback_status') && bug_get_field($p_bug_id, 'reporter_id') == $c_user_id) { if (bug_get_field($p_bug_id, 'handler_id') == 0) { bug_set_field($p_bug_id, 'status', config_get('bug_submit_status')); } else { bug_set_field($p_bug_id, 'status', config_get('bug_assigned_status')); } } # Event integration event_signal('EVENT_BUGNOTE_ADD', array($p_bug_id, $t_bugnote_id)); # only send email if the text is not blank, otherwise, it is just recording of time without a comment. if (TRUE == $p_send_email && !is_blank($t_bugnote_text)) { email_bugnote_add($p_bug_id); } return $t_bugnote_id; }
bug_set_field($f_bug_id, 'status', 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($f_bug_id, 'handler_id'); $t_bug_data->status = bug_get_field($f_bug_id, 'status'); break; case CLOSED: # bug_close updates the status and bugnote and sends message bug_close($f_bug_id, $f_bugnote_text, $f_private, $f_time_tracking); $t_notify = false; $t_bug_note_set = true; break; case config_get('bug_reopen_status'): if ($t_old_bug_status >= $t_resolved) { bug_set_field($f_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($f_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($f_bug_id, 'status'); $t_bug_data->resolution = bug_get_field($f_bug_id, 'resolution'); break; } # else fall through to default } } # Add a bugnote if there is one
} # Handle the file upload if ($f_files !== null) { if (!file_allow_bug_upload($f_bug_id)) { access_denied(); } file_process_posted_files_for_bug($f_bug_id, $f_files); } # We always set the note time to BUGNOTE, and the API will overwrite it with TIME_TRACKING # if $f_time_tracking is not 0 and the time tracking feature is enabled. $t_bugnote_id = bugnote_add($t_bug->id, $f_bugnote_text, $f_time_tracking, $f_private, BUGNOTE); if (!$t_bugnote_id) { error_parameters(lang_get('bugnote')); trigger_error(ERROR_EMPTY_FIELD, ERROR); } # Process the mentions in the added note bugnote_process_mentions($t_bug->id, $t_bugnote_id, $f_bugnote_text); # Handle the reassign on feedback feature. Note that this feature generally # won't work very well with custom workflows as it makes a lot of assumptions # that may not be true. It assumes you don't have any statuses in the workflow # between 'bug_submit_status' and 'bug_feedback_status'. It assumes you only # have one feedback, assigned and submitted status. if (config_get('reassign_on_feedback') && $t_bug->status === config_get('bug_feedback_status') && $t_bug->handler_id !== auth_get_current_user_id() && $t_bug->reporter_id === auth_get_current_user_id()) { if ($t_bug->handler_id !== NO_USER) { bug_set_field($t_bug->id, 'status', config_get('bug_assigned_status')); } else { bug_set_field($t_bug->id, 'status', config_get('bug_submit_status')); } } form_security_purge('bugnote_add'); print_successful_redirect_to_bug($t_bug->id);
/** * reopen the given bug * @param int p_bug_id * @param string p_bugnote_text * @param string p_time_tracking * @param bool p_bugnote_private * @return bool (always true) * @access public * @uses database_api.php * @uses email_api.php * @uses bugnote_api.php * @uses config_api.php */ function bug_reopen($p_bug_id, $p_bugnote_text = '', $p_time_tracking = '0:00', $p_bugnote_private = false) { $p_bugnote_text = trim($p_bugnote_text); # Add bugnote if supplied # Moved bugnote_add before bug_set_field calls in case time_tracking_no_note is off. # Error condition stopped execution but status had already been changed bugnote_add($p_bug_id, $p_bugnote_text, $p_time_tracking, $p_bugnote_private, 0, '', NULL, FALSE); bug_set_field($p_bug_id, 'status', config_get('bug_reopen_status')); bug_set_field($p_bug_id, 'resolution', config_get('bug_reopen_resolution')); email_reopen($p_bug_id); return true; }
/** * Update bug to reflect sponsorship change * This is to be called after adding/updating/deleting sponsorships * @param int $p_bug_id * @return null */ function sponsorship_update_bug($p_bug_id) { $t_total_amount = sponsorship_get_amount(sponsorship_get_all_ids($p_bug_id)); bug_set_field($p_bug_id, 'sponsorship_total', $t_total_amount); bug_update_date($p_bug_id); }
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with MantisBT. If not, see <http://www.gnu.org/licenses/>. /** * This file sticks or unsticks a bug to the top of the view page * * @package MantisBT * @copyright Copyright (C) 2000 - 2002 Kenzaburo Ito - kenito@300baud.org * @copyright Copyright (C) 2002 - 2012 MantisBT Team - mantisbt-dev@lists.sourceforge.net * @link http://www.mantisbt.org */ /** * MantisBT Core API's */ require_once 'core.php'; require_once 'bug_api.php'; form_security_validate('bug_stick'); $f_bug_id = gpc_get_int('bug_id'); $t_bug = bug_get($f_bug_id, true); $f_action = gpc_get_string('action'); if ($t_bug->project_id != helper_get_current_project()) { # in case the current project is not the same project of the bug we are viewing... # ... override the current project. This to avoid problems with categories and handlers lists etc. $g_project_override = $t_bug->project_id; } access_ensure_bug_level(config_get('set_bug_sticky_threshold'), $f_bug_id); bug_set_field($f_bug_id, 'sticky', 'stick' == $f_action); form_security_purge('bug_stick'); print_successful_redirect_to_bug($f_bug_id);
$t_failed_ids[$t_bug_id] = lang_get('bug_actiongroup_access'); } break; case 'VIEW_STATUS': if (access_has_bug_level(config_get('change_view_status_threshold'), $t_bug_id)) { $f_view_status = gpc_get_int('view_status'); bug_set_field($t_bug_id, 'view_state', $f_view_status); } else { $t_failed_ids[$t_bug_id] = lang_get('bug_actiongroup_access'); } break; case 'SET_STICKY': if (access_has_bug_level(config_get('set_bug_sticky_threshold'), $t_bug_id)) { $f_sticky = bug_get_field($t_bug_id, 'sticky'); // The new value is the inverted old value bug_set_field($t_bug_id, 'sticky', !$f_sticky); } 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); } $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); break; default: trigger_error(ERROR_GENERIC, ERROR); }
function updateTrackerHandler($bug_id, $handler_id, $productbacklog_id = "") { $bug = bug_get($bug_id, true); if ($bug->status == 50) { if ($bug->status < 80) { bug_set_field($bug_id, 'status', '50'); } bug_set_field($bug_id, 'handler_id', $handler_id); if ($handler_id == 0 || empty($handler_id)) { bug_set_field($bug_id, 'status', '10'); if ($this->count_productbacklog_teams($productbacklog_id) > 0) { $team_id = $this->getTeamIdByBacklog($productbacklog_id); $product_owner = $this->getProductOwner($team_id); if (!empty($product_owner)) { $handler_id = $this->getUserIdByName($product_owner); bug_set_field($bug_id, 'handler_id', $handler_id); bug_set_field($bug_id, 'status', '50'); } } } } }
/** * 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 bug_reopen($p_bug_id, $p_bugnote_text = '', $p_bugnote_private = false) { $p_bugnote_text = trim($p_bugnote_text); bug_set_field($p_bug_id, 'status', config_get('bug_reopen_status')); bug_set_field($p_bug_id, 'resolution', config_get('bug_reopen_resolution')); # Add bugnote if supplied if (!is_blank($p_bugnote_text)) { bugnote_add($p_bug_id, $p_bugnote_text, $p_bugnote_private); } email_reopen($p_bug_id); return true; }