0byt3m1n1
Path:
/
data
/
applications
/
aps
/
mantis
/
1.1.1-6
/
standard
/
htdocs
/
core
/
[
Home
]
File: history_api.php
<?php # Mantis - a php based bugtracking system # Copyright (C) 2000 - 2002 Kenzaburo Ito - kenito@300baud.org # Copyright (C) 2002 - 2007 Mantis Team - mantisbt-dev@lists.sourceforge.net # Mantis is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # Mantis is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # 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 Mantis. If not, see <http://www.gnu.org/licenses/>. # -------------------------------------------------------- # $Id: history_api.php,v 1.43.2.1 2007-10-13 22:35:31 giallu Exp $ # -------------------------------------------------------- ### History API ### # -------------------- # log the changes (old / new value are supplied to reduce db access) # events should be logged *after* the modification function history_log_event_direct( $p_bug_id, $p_field_name, $p_old_value, $p_new_value, $p_user_id = null ) { # Only log events that change the value if ( $p_new_value != $p_old_value ) { if ( null === $p_user_id ) { $p_user_id = auth_get_current_user_id(); } $c_field_name = db_prepare_string( $p_field_name ); $c_old_value = db_prepare_string( $p_old_value ); $c_new_value = db_prepare_string( $p_new_value ); $c_bug_id = db_prepare_int( $p_bug_id ); $c_user_id = db_prepare_int( $p_user_id ); $t_mantis_bug_history_table = config_get( 'mantis_bug_history_table' ); $query = "INSERT INTO $t_mantis_bug_history_table ( user_id, bug_id, date_modified, field_name, old_value, new_value ) VALUES ( '$c_user_id', '$c_bug_id', " . db_now() . ", '$c_field_name', '$c_old_value', '$c_new_value' )"; $result = db_query( $query ); } } # -------------------- # log the changes # events should be logged *after* the modification function history_log_event( $p_bug_id, $p_field_name, $p_old_value ) { history_log_event_direct( $p_bug_id, $p_field_name, $p_old_value, bug_get_field( $p_bug_id, $p_field_name ) ); } # -------------------- # log the changes # events should be logged *after* the modification # These are special case logs (new bug, deleted bugnote, etc.) function history_log_event_special( $p_bug_id, $p_type, $p_optional='', $p_optional2='' ) { $c_bug_id = db_prepare_int( $p_bug_id ); $c_type = db_prepare_int( $p_type ); $c_optional = db_prepare_string( $p_optional ); $c_optional2 = db_prepare_string( $p_optional2 ); $t_user_id = auth_get_current_user_id(); $t_mantis_bug_history_table = config_get( 'mantis_bug_history_table' ); $query = "INSERT INTO $t_mantis_bug_history_table ( user_id, bug_id, date_modified, type, old_value, new_value, field_name ) VALUES ( '$t_user_id', '$c_bug_id', " . db_now() . ", '$c_type', '$c_optional', '$c_optional2', '' )"; $result = db_query( $query ); } # -------------------- # return all bug history for a given bug id ordered by date function history_get_events( $p_bug_id ) { $t_mantis_bug_history_table = config_get( 'mantis_bug_history_table' ); $t_mantis_user_table = config_get( 'mantis_user_table' ); $c_bug_id = db_prepare_int( $p_bug_id ); $query = "SELECT b.*, u.username FROM $t_bug_history_table b LEFT JOIN $t_mantis_user_table u ON b.user_id=u.id WHERE bug_id='$c_bug_id' ORDER BY date_modified DESC"; $result = db_query( $query ); } # -------------------- # Retrieves the history events for the specified bug id and returns it in an array # The array is indexed from 0 to N-1. The second dimension is: 'date', 'username', # 'note', 'change'. function history_get_events_array( $p_bug_id, $p_user_id = null ) { $t_normal_date_format = config_get( 'normal_date_format' ); $raw_history = history_get_raw_events_array( $p_bug_id, $p_user_id ); $raw_history_count = count( $raw_history ); $history = array(); for ( $i=0; $i < $raw_history_count; $i++ ) { $history[$i] = history_localize_item( $raw_history[$i]['field'], $raw_history[$i]['type'], $raw_history[$i]['old_value'], $raw_history[$i]['new_value'] ); $history[$i]['date'] = date( $t_normal_date_format, $raw_history[$i]['date'] ); $history[$i]['userid'] = $raw_history[$i]['userid']; $history[$i]['username'] = $raw_history[$i]['username']; } return ( $history ); } # -------------------- # Retrieves the raw history events for the specified bug id and returns it in an array # The array is indexed from 0 to N-1. The second dimension is: 'date', 'userid', 'username', # 'field','type','old_value','new_value' function history_get_raw_events_array( $p_bug_id, $p_user_id = null ) { $t_mantis_bug_history_table = config_get( 'mantis_bug_history_table' ); $t_mantis_user_table = config_get( 'mantis_user_table' ); $t_history_order = config_get( 'history_order' ); $c_bug_id = db_prepare_int( $p_bug_id ); $t_user_id = ( ( null === $p_user_id ) ? auth_get_current_user_id() : $p_user_id ); $t_roadmap_view_access_level = config_get( 'roadmap_view_threshold' ); # grab history and display by date_modified then field_name # @@@ by MASC I guess it's better by id then by field_name. When we have more history lines with the same # date, it's better to respect the storing order otherwise we should risk to mix different information # I give you an example. We create a child of a bug with different custom fields. In the history of the child # bug we will find the line related to the relationship mixed with the custom fields (the history is creted # for the new bug with the same timestamp...) $query = "SELECT * FROM $t_mantis_bug_history_table WHERE bug_id='$c_bug_id' ORDER BY date_modified $t_history_order,id"; $result = db_query( $query ); $raw_history_count = db_num_rows( $result ); $raw_history = array(); $t_private_bugnote_threshold = config_get( 'private_bugnote_threshold' ); $t_private_bugnote_visible = access_has_bug_level( config_get( 'private_bugnote_threshold' ), $p_bug_id, $t_user_id ); for ( $i=0,$j=0; $i < $raw_history_count; ++$i ) { $row = db_fetch_array( $result ); extract( $row, EXTR_PREFIX_ALL, 'v' ); // check that the item should be visible to the user // custom fields - we are passing 32 here to notify the API that the custom field name is truncated by the history column from 64 to 32 characters. $t_field_id = custom_field_get_id_from_name( $v_field_name, 32 ); if ( false !== $t_field_id && !custom_field_has_read_access( $t_field_id, $p_bug_id, $t_user_id ) ) { continue; } if ( ( $v_field_name == 'target_version' ) && !access_has_bug_level( $t_roadmap_view_access_level, $p_bug_id, $t_user_id ) ) { continue; } // bugnotes if ( $t_user_id != $v_user_id ) { // bypass if user originated note if ( ( $v_type == BUGNOTE_ADDED ) || ( $v_type == BUGNOTE_UPDATED ) || ( $v_type == BUGNOTE_DELETED ) ) { if ( !$t_private_bugnote_visible && ( bugnote_get_field( $v_old_value, 'view_state' ) == VS_PRIVATE ) ) { continue; } } if ( $v_type == BUGNOTE_STATE_CHANGED ) { if ( !$t_private_bugnote_visible && ( bugnote_get_field( $v_new_value, 'view_state' ) == VS_PRIVATE ) ) { continue; } } } // tags if ( $v_type == TAG_ATTACHED || $v_type == TAG_DETACHED || $v_type == TAG_RENAMED ) { if ( !access_has_global_level( config_get( 'tag_view_threshold' ) ) ) { continue; } } $raw_history[$j]['date'] = db_unixtimestamp( $v_date_modified ); $raw_history[$j]['userid'] = $v_user_id; # user_get_name handles deleted users, and username vs realname $raw_history[$j]['username'] = user_get_name( $v_user_id ); $raw_history[$j]['field'] = $v_field_name; $raw_history[$j]['type'] = $v_type; $raw_history[$j]['old_value'] = $v_old_value; $raw_history[$j]['new_value'] = $v_new_value; $j++; } # end for loop return $raw_history; } # -------------------- # Localizes one raw history item specified by set the next parameters: $p_field_name, $p_type, $p_old_value, $p_new_value # Returns array with two elements indexed as 'note' and 'change' # function history_localize_item( $p_field_name, $p_type, $p_old_value, $p_new_value ) { $t_note = ''; $t_change = ''; $t_field_localized = $p_field_name; switch ( $p_field_name ) { case 'category': $t_field_localized = lang_get( 'category' ); break; case 'status': $p_old_value = get_enum_element( 'status', $p_old_value ); $p_new_value = get_enum_element( 'status', $p_new_value ); $t_field_localized = lang_get( 'status' ); break; case 'severity': $p_old_value = get_enum_element( 'severity', $p_old_value ); $p_new_value = get_enum_element( 'severity', $p_new_value ); $t_field_localized = lang_get( 'severity' ); break; case 'reproducibility': $p_old_value = get_enum_element( 'reproducibility', $p_old_value ); $p_new_value = get_enum_element( 'reproducibility', $p_new_value ); $t_field_localized = lang_get( 'reproducibility' ); break; case 'resolution': $p_old_value = get_enum_element( 'resolution', $p_old_value ); $p_new_value = get_enum_element( 'resolution', $p_new_value ); $t_field_localized = lang_get( 'resolution' ); break; case 'priority': $p_old_value = get_enum_element( 'priority', $p_old_value ); $p_new_value = get_enum_element( 'priority', $p_new_value ); $t_field_localized = lang_get( 'priority' ); break; case 'eta': $p_old_value = get_enum_element( 'eta', $p_old_value ); $p_new_value = get_enum_element( 'eta', $p_new_value ); $t_field_localized = lang_get( 'eta' ); break; case 'view_state': $p_old_value = get_enum_element( 'view_state', $p_old_value ); $p_new_value = get_enum_element( 'view_state', $p_new_value ); $t_field_localized = lang_get( 'view_status' ); break; case 'projection': $p_old_value = get_enum_element( 'projection', $p_old_value ); $p_new_value = get_enum_element( 'projection', $p_new_value ); $t_field_localized = lang_get( 'projection' ); break; case 'sticky': $p_old_value = gpc_string_to_bool( $p_old_value ) ? lang_get( 'yes' ) : lang_get( 'no' ) ; $p_new_value = gpc_string_to_bool( $p_new_value ) ? lang_get( 'yes' ) : lang_get( 'no' ) ; $t_field_localized = lang_get( 'sticky_issue' ); break; case 'project_id': if ( project_exists( $p_old_value ) ) { $p_old_value = project_get_field( $p_old_value, 'name' ); } else { $p_old_value = '@'.$p_old_value.'@'; } # Note that the new value maybe an intermediately project and not the # current one. if ( project_exists( $p_new_value ) ) { $p_new_value = project_get_field( $p_new_value, 'name' ); } else { $p_new_value = '@'.$p_new_value.'@'; } $t_field_localized = lang_get( 'email_project' ); break; case 'handler_id': $t_field_localized = lang_get( 'assigned_to' ); case 'reporter_id': if ( 'reporter_id' == $p_field_name ) { $t_field_localized = lang_get( 'reporter' ); } if ( 0 == $p_old_value ) { $p_old_value = ''; } else { $p_old_value = user_get_name( $p_old_value ); } if ( 0 == $p_new_value ) { $p_new_value = ''; } else { $p_new_value = user_get_name( $p_new_value ); } break; case 'fixed_in_version': $t_field_localized = lang_get( 'fixed_in_version' ); break; case 'target_version': $t_field_localized = lang_get( 'target_version' ); break; case 'date_submitted': $t_field_localized = lang_get( 'date_submitted' ); break; case 'last_updated': $t_field_localized = lang_get( 'last_update' ); break; case 'summary': $t_field_localized = lang_get( 'summary' ); break; case 'duplicate_id': $t_field_localized = lang_get( 'duplicate_id' ); break; case 'sponsorship_total': $t_field_localized = lang_get( 'sponsorship_total' ); break; default: # assume it's a custom field name $t_field_id = custom_field_get_id_from_name( $p_field_name ); if ( false !== $t_field_id ) { $t_cf_type = custom_field_type( $t_field_id ); if ( '' != $p_old_value ) { $p_old_value = string_custom_field_value_for_email( $p_old_value, $t_cf_type ); } $p_new_value = string_custom_field_value_for_email( $p_new_value, $t_cf_type ); } } if ( NORMAL_TYPE != $p_type ) { switch ( $p_type ) { case NEW_BUG: $t_note = lang_get( 'new_bug' ); break; case BUGNOTE_ADDED: $t_note = lang_get( 'bugnote_added' ) . ": " . $p_old_value; break; case BUGNOTE_UPDATED: $t_note = lang_get( 'bugnote_edited' ) . ": " . $p_old_value; break; case BUGNOTE_DELETED: $t_note = lang_get( 'bugnote_deleted' ) . ": " . $p_old_value; break; case DESCRIPTION_UPDATED: $t_note = lang_get( 'description_updated' ); break; case ADDITIONAL_INFO_UPDATED: $t_note = lang_get( 'additional_information_updated' ); break; case STEP_TO_REPRODUCE_UPDATED: $t_note = lang_get( 'steps_to_reproduce_updated' ); break; case FILE_ADDED: $t_note = lang_get( 'file_added' ) . ": " . $p_old_value; break; case FILE_DELETED: $t_note = lang_get( 'file_deleted' ) . ": " . $p_old_value; break; case BUGNOTE_STATE_CHANGED: $p_old_value = get_enum_element( 'view_state', $p_old_value ); $t_note = lang_get( 'bugnote_view_state' ) . ": " . $p_old_value . ": " . $p_new_value; break; case BUG_MONITOR: $p_old_value = user_get_name( $p_old_value ); $t_note = lang_get( 'bug_monitor' ) . ": " . $p_old_value; break; case BUG_UNMONITOR: $p_old_value = user_get_name( $p_old_value ); $t_note = lang_get( 'bug_end_monitor' ) . ": " . $p_old_value; break; case BUG_DELETED: $t_note = lang_get( 'bug_deleted' ) . ": " . $p_old_value; break; case BUG_ADD_SPONSORSHIP: $t_note = lang_get( 'sponsorship_added' ); $t_change = user_get_name( $p_old_value ) . ': ' . sponsorship_format_amount( $p_new_value ); break; case BUG_UPDATE_SPONSORSHIP: $t_note = lang_get( 'sponsorship_updated' ); $t_change = user_get_name( $p_old_value ) . ': ' . sponsorship_format_amount( $p_new_value ); break; case BUG_DELETE_SPONSORSHIP: $t_note = lang_get( 'sponsorship_deleted' ); $t_change = user_get_name( $p_old_value ) . ': ' . sponsorship_format_amount( $p_new_value ); break; case BUG_PAID_SPONSORSHIP: $t_note = lang_get( 'sponsorship_paid' ); $t_change = user_get_name( $p_old_value ) . ': ' . get_enum_element( 'sponsorship', $p_new_value ); break; case BUG_ADD_RELATIONSHIP: $t_note = lang_get( 'relationship_added' ); $t_change = relationship_get_description_for_history( $p_old_value ) . ' ' . bug_format_id( $p_new_value ); break; case BUG_REPLACE_RELATIONSHIP: $t_note = lang_get( 'relationship_replaced' ); $t_change = relationship_get_description_for_history( $p_old_value ) . ' ' . bug_format_id( $p_new_value ); break; case BUG_DEL_RELATIONSHIP: $t_note = lang_get( 'relationship_deleted' ); # Fix for #7846: There are some cases where old value is empty, this may be due to an old bug. if ( !is_blank( $p_old_value ) && $p_old_value > 0 ) { $t_change = relationship_get_description_for_history( $p_old_value ) . ' ' . bug_format_id( $p_new_value ); } else { $t_change = bug_format_id( $p_new_value ); } break; case BUG_CLONED_TO: $t_note = lang_get( 'bug_cloned_to' ); $t_change = bug_format_id( $p_new_value ); break; case BUG_CREATED_FROM: $t_note = lang_get( 'bug_created_from' ); $t_change = bug_format_id( $p_new_value ); break; case CHECKIN: $t_note = lang_get( 'checkin' ); break; case TAG_ATTACHED: $t_note = lang_get( 'tag_history_attached' ) .': '. $p_old_value; break; case TAG_DETACHED: $t_note = lang_get( 'tag_history_detached' ) .': '. $p_old_value; break; case TAG_RENAMED: $t_note = lang_get( 'tag_history_renamed' ); $t_change = $p_old_value . ' => ' . $p_new_value; break; } } # output special cases if ( NORMAL_TYPE == $p_type ) { $t_note = $t_field_localized; $t_change = $p_old_value . ' => ' . $p_new_value; } # end if DEFAULT return array( 'note' => $t_note, 'change' => $t_change ); } # -------------------- # delete all history associated with a bug function history_delete( $p_bug_id ) { $c_bug_id = db_prepare_int( $p_bug_id ); $t_bug_history_table = config_get( 'mantis_bug_history_table' ); $query = "DELETE FROM $t_bug_history_table WHERE bug_id='$c_bug_id'"; db_query($query); # db_query() errors on failure so: return true; } ?>