/** * Update a bug from the given data structure * If the third parameter is true, also update the longer strings table * @param bool p_update_extended * @param bool p_bypass_email Default false, set to true to avoid generating emails (if sending elsewhere) * @return bool (always true) * @access public */ function update($p_update_extended = false, $p_bypass_mail = false) { self::validate($p_update_extended); $c_bug_id = $this->id; if (is_blank($this->due_date)) { $this->due_date = date_get_null(); } $t_old_data = bug_get($this->id, true); $t_bug_table = db_get_table('mantis_bug_table'); # Update all fields # Ignore date_submitted and last_updated since they are pulled out # as unix timestamps which could confuse the history log and they # shouldn't get updated like this anyway. If you really need to change # them use bug_set_field() $query = "UPDATE {$t_bug_table}\n\t\t\t\t\tSET project_id=" . db_param() . ', reporter_id=' . db_param() . ",\n\t\t\t\t\t\thandler_id=" . db_param() . ', duplicate_id=' . db_param() . ",\n\t\t\t\t\t\tpriority=" . db_param() . ', severity=' . db_param() . ",\n\t\t\t\t\t\treproducibility=" . db_param() . ', status=' . db_param() . ",\n\t\t\t\t\t\tresolution=" . db_param() . ', projection=' . db_param() . ",\n\t\t\t\t\t\tcategory_id=" . db_param() . ', eta=' . db_param() . ",\n\t\t\t\t\t\tos=" . db_param() . ', os_build=' . db_param() . ",\n\t\t\t\t\t\tplatform=" . db_param() . ', version=' . db_param() . ",\n\t\t\t\t\t\tbuild=" . db_param() . ', fixed_in_version=' . db_param() . ','; $t_fields = array($this->project_id, $this->reporter_id, $this->handler_id, $this->duplicate_id, $this->priority, $this->severity, $this->reproducibility, $this->status, $this->resolution, $this->projection, $this->category_id, $this->eta, $this->os, $this->os_build, $this->platform, $this->version, $this->build, $this->fixed_in_version); $t_roadmap_updated = false; if (access_has_project_level(config_get('roadmap_update_threshold'))) { $query .= "\n\t\t\t\t\t\ttarget_version=" . db_param() . ","; $t_fields[] = $this->target_version; $t_roadmap_updated = true; } $query .= "\n\t\t\t\t\t\tview_state=" . db_param() . ",\n\t\t\t\t\t\tsummary=" . db_param() . ",\n\t\t\t\t\t\tsponsorship_total=" . db_param() . ",\n\t\t\t\t\t\tsticky=" . db_param() . ",\n\t\t\t\t\t\tdue_date=" . db_param() . "\n\t\t\t\t\tWHERE id=" . db_param(); $t_fields[] = $this->view_state; $t_fields[] = $this->summary; $t_fields[] = $this->sponsorship_total; $t_fields[] = (bool) $this->sticky; $t_fields[] = $this->due_date; $t_fields[] = $this->id; db_query_bound($query, $t_fields); bug_clear_cache($this->id); # log changes history_log_event_direct($c_bug_id, 'project_id', $t_old_data->project_id, $this->project_id); history_log_event_direct($c_bug_id, 'reporter_id', $t_old_data->reporter_id, $this->reporter_id); history_log_event_direct($c_bug_id, 'handler_id', $t_old_data->handler_id, $this->handler_id); history_log_event_direct($c_bug_id, 'priority', $t_old_data->priority, $this->priority); history_log_event_direct($c_bug_id, 'severity', $t_old_data->severity, $this->severity); history_log_event_direct($c_bug_id, 'reproducibility', $t_old_data->reproducibility, $this->reproducibility); history_log_event_direct($c_bug_id, 'status', $t_old_data->status, $this->status); history_log_event_direct($c_bug_id, 'resolution', $t_old_data->resolution, $this->resolution); history_log_event_direct($c_bug_id, 'projection', $t_old_data->projection, $this->projection); history_log_event_direct($c_bug_id, 'category', category_full_name($t_old_data->category_id, false), category_full_name($this->category_id, false)); history_log_event_direct($c_bug_id, 'eta', $t_old_data->eta, $this->eta); history_log_event_direct($c_bug_id, 'os', $t_old_data->os, $this->os); history_log_event_direct($c_bug_id, 'os_build', $t_old_data->os_build, $this->os_build); history_log_event_direct($c_bug_id, 'platform', $t_old_data->platform, $this->platform); history_log_event_direct($c_bug_id, 'version', $t_old_data->version, $this->version); history_log_event_direct($c_bug_id, 'build', $t_old_data->build, $this->build); history_log_event_direct($c_bug_id, 'fixed_in_version', $t_old_data->fixed_in_version, $this->fixed_in_version); if ($t_roadmap_updated) { history_log_event_direct($c_bug_id, 'target_version', $t_old_data->target_version, $this->target_version); } history_log_event_direct($c_bug_id, 'view_state', $t_old_data->view_state, $this->view_state); history_log_event_direct($c_bug_id, 'summary', $t_old_data->summary, $this->summary); history_log_event_direct($c_bug_id, 'sponsorship_total', $t_old_data->sponsorship_total, $this->sponsorship_total); history_log_event_direct($c_bug_id, 'sticky', $t_old_data->sticky, $this->sticky); history_log_event_direct($c_bug_id, 'due_date', $t_old_data->due_date != date_get_null() ? $t_old_data->due_date : null, $this->due_date != date_get_null() ? $this->due_date : null); # Update extended info if requested if ($p_update_extended) { $t_bug_text_table = db_get_table('mantis_bug_text_table'); $t_bug_text_id = bug_get_field($c_bug_id, 'bug_text_id'); $query = "UPDATE {$t_bug_text_table}\n\t\t\t\t\t\t\tSET description=" . db_param() . ",\n\t\t\t\t\t\t\t\tsteps_to_reproduce=" . db_param() . ",\n\t\t\t\t\t\t\t\tadditional_information=" . db_param() . "\n\t\t\t\t\t\t\tWHERE id=" . db_param(); db_query_bound($query, array($this->description, $this->steps_to_reproduce, $this->additional_information, $t_bug_text_id)); bug_text_clear_cache($c_bug_id); $t_current_user = auth_get_current_user_id(); if ($t_old_data->description != $this->description) { if (bug_revision_count($c_bug_id, REV_DESCRIPTION) < 1) { $t_revision_id = bug_revision_add($c_bug_id, $t_old_data->reporter_id, REV_DESCRIPTION, $t_old_data->description, 0, $t_old_data->date_submitted); } $t_revision_id = bug_revision_add($c_bug_id, $t_current_user, REV_DESCRIPTION, $this->description); history_log_event_special($c_bug_id, DESCRIPTION_UPDATED, $t_revision_id); } if ($t_old_data->steps_to_reproduce != $this->steps_to_reproduce) { if (bug_revision_count($c_bug_id, REV_STEPS_TO_REPRODUCE) < 1) { $t_revision_id = bug_revision_add($c_bug_id, $t_old_data->reporter_id, REV_STEPS_TO_REPRODUCE, $t_old_data->steps_to_reproduce, 0, $t_old_data->date_submitted); } $t_revision_id = bug_revision_add($c_bug_id, $t_current_user, REV_STEPS_TO_REPRODUCE, $this->steps_to_reproduce); history_log_event_special($c_bug_id, STEP_TO_REPRODUCE_UPDATED, $t_revision_id); } if ($t_old_data->additional_information != $this->additional_information) { if (bug_revision_count($c_bug_id, REV_ADDITIONAL_INFO) < 1) { $t_revision_id = bug_revision_add($c_bug_id, $t_old_data->reporter_id, REV_ADDITIONAL_INFO, $t_old_data->additional_information, 0, $t_old_data->date_submitted); } $t_revision_id = bug_revision_add($c_bug_id, $t_current_user, REV_ADDITIONAL_INFO, $this->additional_information); history_log_event_special($c_bug_id, ADDITIONAL_INFO_UPDATED, $t_revision_id); } } # Update the last update date bug_update_date($c_bug_id); # allow bypass if user is sending mail separately if (false == $p_bypass_mail) { # bug assigned if ($t_old_data->handler_id != $this->handler_id) { email_generic($c_bug_id, 'owner', 'email_notification_title_for_action_bug_assigned'); return true; } # status changed if ($t_old_data->status != $this->status) { $t_status = MantisEnum::getLabel(config_get('status_enum_string'), $this->status); $t_status = str_replace(' ', '_', $t_status); email_generic($c_bug_id, $t_status, 'email_notification_title_for_status_bug_' . $t_status); return true; } # @todo handle priority change if it requires special handling # generic update notification email_generic($c_bug_id, 'updated', 'email_notification_title_for_action_bug_updated'); } return true; }
if ($t_resolve_issue) { email_resolved($f_bug_id); email_relationship_child_resolved($f_bug_id); } else { if ($t_close_issue) { email_close($f_bug_id); email_relationship_child_closed($f_bug_id); } else { if ($t_reopen_issue) { email_reopen($f_bug_id); } else { if ($t_existing_bug->handler_id === NO_USER && $t_updated_bug->handler_id !== NO_USER) { email_assign($f_bug_id); } else { if ($t_existing_bug->status !== $t_updated_bug->status) { $t_new_status_label = MantisEnum::getLabel(config_get('status_enum_string'), $t_updated_bug->status); $t_new_status_label = str_replace(' ', '_', $t_new_status_label); email_generic($f_bug_id, $t_new_status_label, 'email_notification_title_for_status_bug_' . $t_new_status_label); } else { email_generic($f_bug_id, 'updated', 'email_notification_title_for_action_bug_updated'); } } } } } # Twitter notification of bug update. if ($t_resolve_issue && $t_updated_bug->resolution >= config_get('bug_resolution_fixed_threshold') && $t_updated_bug->resolution < config_get('bug_resolution_not_fixed_threshold')) { twitter_issue_resolved($f_bug_id); } form_security_purge('bug_update'); print_successful_redirect_to_bug($f_bug_id);
/** * Add an issue to the database. * * @param string $p_username The name of the user trying to add the issue. * @param string $p_password The password of the user. * @param stdClass $p_issue A IssueData structure containing information about the new issue. * @return integer The id of the created issue. */ function mc_issue_add( $p_username, $p_password, stdClass $p_issue ) { global $g_project_override; $t_user_id = mci_check_login( $p_username, $p_password ); if( $t_user_id === false ) { return mci_soap_fault_login_failed(); } $p_issue = SoapObjectsFactory::unwrapObject( $p_issue ); $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_soap_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_soap_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 SoapObjectsFactory::newSoapFault( 'Client', "Project '" . $t_project['name'] . "' does not exist." ); } else { return SoapObjectsFactory::newSoapFault( 'Client', "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_soap_fault_access_denied( 'User \'' . $t_user_id . '\' 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 = translate_category_name_to_id( $t_category, $t_project_id ); if( $t_category_id == 0 && !config_get( 'allow_no_category' ) ) { if( !isset( $p_issue['category'] ) || is_blank( $p_issue['category'] ) ) { return SoapObjectsFactory::newSoapFault( 'Client', 'Category field must be supplied.' ); } else { return SoapObjectsFactory::newSoapFault( 'Client', 'Category \'' . $p_issue['category'] . '\' not found for project \'' . $t_project_id . '\'.' ); } } if( isset( $p_issue['version'] ) && !is_blank( $p_issue['version'] ) && !version_get_id( $p_issue['version'], $t_project_id ) ) { $t_version = $p_issue['version']; $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( $t_project_id ); return SoapObjectsFactory::newSoapFault( 'Client', 'Version \'' . $t_version . '\' does not exist in project \'' . $t_project_name . '\'.' ); } else { $t_version_when_not_found = config_get( 'webservice_version_when_not_found' ); $t_version = $t_version_when_not_found; } } if( is_blank( $t_summary ) ) { return SoapObjectsFactory::newSoapFault( 'Client', 'Mandatory field \'summary\' is missing.' ); } if( is_blank( $t_description ) ) { return SoapObjectsFactory::newSoapFault( 'Client', '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'] ) ? $p_issue['date_submitted'] : ''; $t_bug_data->last_updated = isset( $p_issue['last_updated'] ) ? $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'] : ''; $t_bug_data->version = isset( $p_issue['version'] ) ? $p_issue['version'] : ''; $t_bug_data->fixed_in_version = isset( $p_issue['fixed_in_version'] ) ? $p_issue['fixed_in_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_global_level( config_get( 'due_date_update_threshold' ) ) ) { $t_bug_data->due_date = SoapObjectsFactory::parseDateTimeString( $p_issue['due_date'] ); } else { $t_bug_data->due_date = date_get_null(); } if( access_has_project_level( config_get( 'roadmap_update_threshold' ), $t_bug_data->project_id, $t_user_id ) ) { $t_bug_data->target_version = isset( $p_issue['target_version'] ) ? $p_issue['target_version'] : ''; } # 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(); log_event( LOG_WEBSERVICE, 'created new issue id \'' . $t_issue_id . '\'' ); $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 = SoapObjectsFactory::unwrapObject( $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 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'] ) ) { mci_tag_set_for_issue( $t_issue_id, $p_issue['tags'], $t_user_id ); } email_generic( $t_issue_id, 'new', 'email_notification_title_for_action_bug_submitted' ); if( $t_bug_data->status != config_get( 'bug_submit_status' ) ) { history_log_event( $t_issue_id, 'status', config_get( 'bug_submit_status' ) ); } if( $t_bug_data->resolution != config_get( 'default_bug_resolution' ) ) { history_log_event( $t_issue_id, 'resolution', config_get( 'default_bug_resolution' ) ); } return $t_issue_id; }
/** * send notices when a bug is DELETED * @param int $p_bug_id * @return null */ function email_bug_deleted($p_bug_id) { email_generic($p_bug_id, 'deleted', 'email_notification_title_for_action_bug_deleted'); }
/** * send notices when a bug is DELETED * @param int $p_bug_id * @return null */ function email_bug_deleted($p_bug_id) { log_event(LOG_EMAIL, sprintf('Issue #%d deleted', $p_bug_id)); email_generic($p_bug_id, 'deleted', 'email_notification_title_for_action_bug_deleted'); }
/** * Add a bugnote to a bug * return the ID of the new bugnote * @param integer $p_bug_id A bug identifier. * @param string $p_bugnote_text The bugnote text to add. * @param string $p_time_tracking Time tracking value - hh:mm string. * @param boolean $p_private Whether bugnote is private. * @param integer $p_type The bugnote type. * @param string $p_attr Bugnote Attribute. * @param integer $p_user_id A user identifier. * @param boolean $p_send_email Whether to generate email. * @param integer $p_date_submitted Date submitted (defaults to now()). * @param integer $p_last_modified Last modification date (defaults to now()). * @param boolean $p_skip_bug_update Skip bug last modification update (useful when importing bugs/bugnotes). * @param boolean $p_log_history Log changes to bugnote history (defaults to true). * @return boolean|integer 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_date_submitted = 0, $p_last_modified = 0, $p_skip_bug_update = false, $p_log_history = true) { $c_bug_id = (int) $p_bug_id; $c_time_tracking = helper_duration_to_minutes($p_time_tracking); $c_type = (int) $p_type; $c_date_submitted = $p_date_submitted <= 0 ? db_now() : (int) $p_date_submitted; $c_last_modified = $p_last_modified <= 0 ? db_now() : (int) $p_last_modified; 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; } } } # Event integration $t_bugnote_text = event_signal('EVENT_BUGNOTE_DATA', $p_bugnote_text, $c_bug_id); # insert bugnote text $t_query = 'INSERT INTO {bugnote_text} ( note ) VALUES ( ' . db_param() . ' )'; db_query($t_query, array($t_bugnote_text)); # retrieve bugnote text id number $t_bugnote_text_id = db_insert_id(db_get_table('bugnote_text')); # get user information if ($p_user_id === null) { $p_user_id = auth_get_current_user_id(); } # Check for private bugnotes. if ($p_private && access_has_bug_level(config_get('set_view_status_threshold'), $p_bug_id, $p_user_id)) { $t_view_state = VS_PRIVATE; } else { $t_view_state = VS_PUBLIC; } # insert bugnote info $t_query = 'INSERT INTO {bugnote} (bug_id, reporter_id, bugnote_text_id, view_state, date_submitted, last_modified, note_type, note_attr, time_tracking) VALUES (' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ', ' . db_param() . ' )'; $t_params = array($c_bug_id, $p_user_id, $t_bugnote_text_id, $t_view_state, $c_date_submitted, $c_last_modified, $c_type, $p_attr, $c_time_tracking); db_query($t_query, $t_params); # get bugnote id $t_bugnote_id = db_insert_id(db_get_table('bugnote')); # update bug last updated if (!$p_skip_bug_update) { 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)); } # 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_generic($p_bug_id, 'bugnote', 'email_notification_title_for_action_bugnote_submitted'); } return $t_bugnote_id; }
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, 0, 0, false); } } # copy attachments from parent if ($f_copy_attachments_from_parent) { file_copy_attachments($f_master_bug_id, $t_bug_id); } } 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_generic($t_bug_id, 'new', 'email_notification_title_for_action_bug_submitted'); # 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')); } form_security_purge('bug_report'); html_page_top1(); if (!$f_report_stay) { html_meta_redirect('view_all_bug_page.php'); } html_page_top2(); echo '<div class="success-msg">'; echo lang_get('operation_successful') . '<br />';
/** * send notices to all the handlers of the parent bugs still open when a child bug is resolved/closed * * @param integer $p_bug_id A bug identifier. * @param integer $p_message_id A message identifier. * @return void */ function email_relationship_child_resolved_closed($p_bug_id, $p_message_id) { # retrieve all the relationships in which the bug is the destination bug $t_relationship = relationship_get_all_dest($p_bug_id); $t_relationship_count = count($t_relationship); if ($t_relationship_count == 0) { # no parent bug found return; } for ($i = 0; $i < $t_relationship_count; $i++) { if ($t_relationship[$i]->type == BUG_DEPENDANT) { $t_src_bug_id = $t_relationship[$i]->src_bug_id; $t_status = bug_get_field($t_src_bug_id, 'status'); if ($t_status < config_get('bug_resolved_status_threshold')) { # sent the notification just for parent bugs not resolved/closed $t_opt = array(); $t_opt[] = bug_format_id($p_bug_id); email_generic($t_src_bug_id, 'handler', $p_message_id, $t_opt); } } } }
function bug_update($p_bug_id, $p_bug_data, $p_update_extended = false, $p_bypass_mail = false) { $c_bug_id = db_prepare_int($p_bug_id); $c_bug_data = bug_prepare_db($p_bug_data); # Summary cannot be blank if (is_blank($c_bug_data->summary)) { error_parameters(lang_get('summary')); trigger_error(ERROR_EMPTY_FIELD, ERROR); } if ($p_update_extended) { # Description field cannot be empty if (is_blank($c_bug_data->description)) { error_parameters(lang_get('description')); trigger_error(ERROR_EMPTY_FIELD, ERROR); } } if (!is_blank($p_bug_data->duplicate_id) && $p_bug_data->duplicate_id != 0 && $p_bug_id == $p_bug_data->duplicate_id) { trigger_error(ERROR_BUG_DUPLICATE_SELF, ERROR); # never returns } $t_old_data = bug_get($p_bug_id, true); $t_bug_table = config_get('mantis_bug_table'); # Update all fields # Ignore date_submitted and last_updated since they are pulled out # as unix timestamps which could confuse the history log and they # shouldn't get updated like this anyway. If you really need to change # them use bug_set_field() $query = "UPDATE {$t_bug_table}\n\t\t\t\tSET project_id='{$c_bug_data->project_id}',\n\t\t\t\t\treporter_id='{$c_bug_data->reporter_id}',\n\t\t\t\t\thandler_id='{$c_bug_data->handler_id}',\n\t\t\t\t\tduplicate_id='{$c_bug_data->duplicate_id}',\n\t\t\t\t\tpriority='{$c_bug_data->priority}',\n\t\t\t\t\tseverity='{$c_bug_data->severity}',\n\t\t\t\t\treproducibility='{$c_bug_data->reproducibility}',\n\t\t\t\t\tstatus='{$c_bug_data->status}',\n\t\t\t\t\tresolution='{$c_bug_data->resolution}',\n\t\t\t\t\tprojection='{$c_bug_data->projection}',\n\t\t\t\t\tcategory='{$c_bug_data->category}',\n\t\t\t\t\teta='{$c_bug_data->eta}',\n\t\t\t\t\tos='{$c_bug_data->os}',\n\t\t\t\t\tos_build='{$c_bug_data->os_build}',\n\t\t\t\t\tplatform='{$c_bug_data->platform}',\n\t\t\t\t\tversion='{$c_bug_data->version}',\n\t\t\t\t\tbuild='{$c_bug_data->build}',\n\t\t\t\t\tfixed_in_version='{$c_bug_data->fixed_in_version}',"; $t_roadmap_updated = false; if (access_has_project_level(config_get('roadmap_update_threshold'))) { $query .= "\n\t\t\t\t\ttarget_version='{$c_bug_data->target_version}',"; $t_roadmap_updated = true; } $query .= "\n\t\t\t\t\tview_state='{$c_bug_data->view_state}',\n\t\t\t\t\tsummary='{$c_bug_data->summary}',\n\t\t\t\t\tsponsorship_total='{$c_bug_data->sponsorship_total}',\n\t\t\t\t\tsticky='{$c_bug_data->sticky}'\n\t\t\t\tWHERE id='{$c_bug_id}'"; db_query($query); bug_clear_cache($p_bug_id); # log changes history_log_event_direct($p_bug_id, 'project_id', $t_old_data->project_id, $p_bug_data->project_id); history_log_event_direct($p_bug_id, 'reporter_id', $t_old_data->reporter_id, $p_bug_data->reporter_id); history_log_event_direct($p_bug_id, 'handler_id', $t_old_data->handler_id, $p_bug_data->handler_id); history_log_event_direct($p_bug_id, 'duplicate_id', $t_old_data->duplicate_id, $p_bug_data->duplicate_id); history_log_event_direct($p_bug_id, 'priority', $t_old_data->priority, $p_bug_data->priority); history_log_event_direct($p_bug_id, 'severity', $t_old_data->severity, $p_bug_data->severity); history_log_event_direct($p_bug_id, 'reproducibility', $t_old_data->reproducibility, $p_bug_data->reproducibility); history_log_event_direct($p_bug_id, 'status', $t_old_data->status, $p_bug_data->status); history_log_event_direct($p_bug_id, 'resolution', $t_old_data->resolution, $p_bug_data->resolution); history_log_event_direct($p_bug_id, 'projection', $t_old_data->projection, $p_bug_data->projection); history_log_event_direct($p_bug_id, 'category', $t_old_data->category, $p_bug_data->category); history_log_event_direct($p_bug_id, 'eta', $t_old_data->eta, $p_bug_data->eta); history_log_event_direct($p_bug_id, 'os', $t_old_data->os, $p_bug_data->os); history_log_event_direct($p_bug_id, 'os_build', $t_old_data->os_build, $p_bug_data->os_build); history_log_event_direct($p_bug_id, 'platform', $t_old_data->platform, $p_bug_data->platform); history_log_event_direct($p_bug_id, 'version', $t_old_data->version, $p_bug_data->version); history_log_event_direct($p_bug_id, 'build', $t_old_data->build, $p_bug_data->build); history_log_event_direct($p_bug_id, 'fixed_in_version', $t_old_data->fixed_in_version, $p_bug_data->fixed_in_version); if ($t_roadmap_updated) { history_log_event_direct($p_bug_id, 'target_version', $t_old_data->target_version, $p_bug_data->target_version); } history_log_event_direct($p_bug_id, 'view_state', $t_old_data->view_state, $p_bug_data->view_state); history_log_event_direct($p_bug_id, 'summary', $t_old_data->summary, $p_bug_data->summary); history_log_event_direct($p_bug_id, 'sponsorship_total', $t_old_data->sponsorship_total, $p_bug_data->sponsorship_total); history_log_event_direct($p_bug_id, 'sticky', $t_old_data->sticky, $p_bug_data->sticky); # Update extended info if requested if ($p_update_extended) { $t_bug_text_table = config_get('mantis_bug_text_table'); $t_bug_text_id = bug_get_field($p_bug_id, 'bug_text_id'); $query = "UPDATE {$t_bug_text_table}\n\t\t\t\t\t\tSET description='{$c_bug_data->description}',\n\t\t\t\t\t\t\tsteps_to_reproduce='{$c_bug_data->steps_to_reproduce}',\n\t\t\t\t\t\t\tadditional_information='{$c_bug_data->additional_information}'\n\t\t\t\t\t\tWHERE id='{$t_bug_text_id}'"; db_query($query); bug_text_clear_cache($p_bug_id); if ($t_old_data->description != $p_bug_data->description) { history_log_event_special($p_bug_id, DESCRIPTION_UPDATED); } if ($t_old_data->steps_to_reproduce != $p_bug_data->steps_to_reproduce) { history_log_event_special($p_bug_id, STEP_TO_REPRODUCE_UPDATED); } if ($t_old_data->additional_information != $p_bug_data->additional_information) { history_log_event_special($p_bug_id, ADDITIONAL_INFO_UPDATED); } } # Update the last update date bug_update_date($p_bug_id); if (false == $p_bypass_mail) { # allow bypass if user is sending mail separately $t_action_prefix = 'email_notification_title_for_action_bug_'; $t_status_prefix = 'email_notification_title_for_status_bug_'; # status changed if ($t_old_data->status != $p_bug_data->status) { $t_status = get_enum_to_string(config_get('status_enum_string'), $p_bug_data->status); $t_status = str_replace(' ', '_', $t_status); email_generic($p_bug_id, $t_status, $t_status_prefix . $t_status); return true; } # bug assigned if ($t_old_data->handler_id != $p_bug_data->handler_id) { email_generic($p_bug_id, 'owner', $t_action_prefix . 'assigned'); return true; } # @@@ handle priority change if it requires special handling # generic update notification email_generic($p_bug_id, 'updated', $t_action_prefix . 'updated'); } return true; }
/** * delete a sponsorship given its id * id can be an array of ids or just an id. * @param integer $p_sponsorship_id The sponsorship identifier to delete. * @return void */ function sponsorship_delete($p_sponsorship_id) { # handle the case of array of ids if (is_array($p_sponsorship_id)) { foreach ($p_sponsorship_id as $t_id) { sponsorship_delete($t_id); } return; } $t_sponsorship = sponsorship_get($p_sponsorship_id); # Delete the bug entry $t_query = 'DELETE FROM {sponsorship} WHERE id=' . db_param(); db_query($t_query, array((int) $p_sponsorship_id)); sponsorship_clear_cache($p_sponsorship_id); history_log_event_special($t_sponsorship->bug_id, BUG_DELETE_SPONSORSHIP, $t_sponsorship->user_id, $t_sponsorship->amount); sponsorship_update_bug($t_sponsorship->bug_id); email_generic($t_sponsorship->bug_id, 'sponsor', 'A sponsorship of the following issue was withdrawn.'); }
function event_view_bug_details($p_event, $p_project_id) { global $agilemantis_sprint; global $agilemantis_pb; global $agilemantis_commonlib; // Only projects with agilMantis backlog if (!$agilemantis_commonlib->projectHasBacklogs(helper_get_current_project())) { return; } if ($_SESSION['AGILEMANTIS_ISMANTISADMIN'] == 1 || $_SESSION['AGILEMANTIS_ISMANTISUSER'] == 1) { if ($_POST['saveValues']) { $agilemantis_pb->setCustomFieldValues($p_project_id); bug_update_date($p_project_id); if ((int) $_GET['bug_id']) { header('Location:' . $_SERVER['PHP_SELF'] . '?bug_id=' . $p_project_id . '&save=true'); } else { header('Location:' . $_SERVER['PHP_SELF'] . '?id=' . $p_project_id . '&save=true'); } email_generic($p_project_id, 'updated', 'email_notification_title_for_action_bug_updated'); } $pbl = $agilemantis_pb->getProjectProductBacklogs(helper_get_current_project()); $story = $agilemantis_pb->checkForUserStory($p_project_id); $s = $agilemantis_sprint->getBacklogSprints($story['name']); // check wether bugnotes are available or not $t_bugnotes = bugnote_get_all_bugnotes($p_project_id); $t_amount_bugnotes = count($t_bugnotes); // activate or disable bugnotes link $bugnotes_disable = ''; if ($t_amount_bugnotes > 0) { $bugnotes_disable = '<a href="#bugnotes">' . plugin_lang_get('view_issue_look_through_notes') . '</a>'; } $pb_name = $story['name']; $sprint_name = $story['sprint']; $disable_sprint_button = ''; if ($sprint_name == "") { $disable_sprint_button = 'disabled'; } else { if (plugin_config_get('gadiv_taskboard') == 0) { $page_backlog = plugin_page("sprint_backlog.php"); } else { $page_backlog = plugin_page("taskboard.php"); } } require_once AGILEMANTIS_CORE_URI . "agile_mantis_custom_fields_inc.php"; if ($_GET['save'] == true) { $hinweis = '<span class="message_ok">' . plugin_lang_get('view_issue_successfully_saved') . '</span>'; } else { $hinweis = ''; } if ($story['name'] == "") { $task_disable = 'disabled'; } echo ' <tr ' . helper_alternate_class() . '> <td class="custom_field_form">agileMantis-' . plugin_lang_get('common_actions') . '</td> <td colspan="5"> <input type="submit" name="saveValues" value="' . plugin_lang_get('view_issue_save_infos') . '"> </form> <form action="' . plugin_page("task_page.php") . '&us_id=' . $p_project_id . '" method="post"> <input type="submit" value="' . plugin_lang_get('view_issue_edit_tasks') . '" ' . $task_disable . '> </form> <form action="' . plugin_page("product_backlog.php") . '" method="post"> <input type="submit" value="' . plugin_lang_get('view_issue_goto_product_backlog') . '" ' . $task_disable . '> <input type="hidden" name="productBacklogName" value="' . $pb_name . '"> </form> <form action="' . $page_backlog . '" method="post"> <input type="submit" value="' . plugin_lang_get('view_issue_goto_sprint_backlog') . '" ' . $disable_sprint_button . '> <input type="hidden" name="sprintName" value="' . $sprint_name . '"> </form> ' . $bugnotes_disable . ' ' . $hinweis . ' </td> </tr> '; } }