View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0016774 | mantisbt | customization | public | 2013-12-30 17:10 | 2022-07-13 05:55 |
Reporter | Mr.Bricodage | Assigned To | |||
Priority | normal | Severity | feature | Reproducibility | always |
Status | new | Resolution | open | ||
Product Version | 1.2.15 | ||||
Summary | 0016774: Ask for the Target version when an issue is confirmed | ||||
Description | With the provided modifications, Mantis can ask for the target version when a bug is confirmed and the status is changed to a predefined status. | ||||
Steps To Reproduce | 1) add the following content to "config_inc.php" /**
2) Modify the file "bug_change_status_page.php" 2-2)Line 184 - Add the following content (between "Assigned To" and due date sections) <!-- Ask for Target Version in a list that contain only FUTURE versions (not released) --> | ||||
Additional Information | The attached file contain the modification made on file "bug_change_status_page.php" from mantis 1.2-15 version | ||||
Tags | patch | ||||
Attached Files | bug_change_status_page.php (12,516 bytes)
<?php # MantisBT - a php based bugtracking system # MantisBT 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. # # MantisBT 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 MantisBT. If not, see <http://www.gnu.org/licenses/>. /** * @package MantisBT * @copyright Copyright (C) 2000 - 2002 Kenzaburo Ito - kenito@300baud.org * @copyright Copyright (C) 2002 - 2013 MantisBT Team - mantisbt-dev@lists.sourceforge.net * @link http://www.mantisbt.org */ /** * MantisBT Core API's */ $g_allow_browser_cache = 1; require_once( 'core.php' ); require_once( 'bug_api.php' ); require_once( 'custom_field_api.php' ); require_once( 'relationship_api.php' ); define ( 'BUG_VIEW_INC_ALLOW', true ); $f_bug_id = gpc_get_int( 'id' ); $t_bug = bug_get( $f_bug_id ); $tpl_file = __FILE__; $tpl_mantis_dir = dirname( __FILE__ ) . DIRECTORY_SEPARATOR; $tpl_show_page_header = false; $tpl_force_readonly = true; $tpl_fields_config_option = 'bug_change_status_page_fields'; 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; } $f_new_status = gpc_get_int( 'new_status' ); $f_reopen_flag = gpc_get_int( 'reopen_flag', OFF ); $t_reopen = config_get( 'bug_reopen_status', null, null, $t_bug->project_id ); $t_confirmed = config_get( 'bug_confirmed_status_threshold', null, null, $t_bug->project_id ); $t_resolved = config_get( 'bug_resolved_status_threshold', null, null, $t_bug->project_id ); $t_closed = config_get( 'bug_closed_status_threshold', null, null, $t_bug->project_id ); $t_current_user_id = auth_get_current_user_id(); # Ensure user has proper access level before proceeding if( $f_new_status == $t_reopen && $f_reopen_flag ) { access_ensure_can_reopen_bug( $t_bug, $t_current_user_id ); } else if( $f_new_status == $t_closed ) { access_ensure_can_close_bug( $t_bug, $t_current_user_id ); } else if ( bug_is_readonly( $f_bug_id ) || !access_has_bug_level( access_get_status_threshold( $f_new_status, $t_bug->project_id ), $f_bug_id, $t_current_user_id ) ) { access_denied(); } $t_can_update_due_date = access_has_bug_level( config_get( 'due_date_update_threshold' ), $f_bug_id ); # get new issue handler if set, otherwise default to original handler $f_handler_id = gpc_get_int( 'handler_id', $t_bug->handler_id ); if ( config_get( 'bug_assigned_status' ) == $f_new_status ) { $t_bug_sponsored = sponsorship_get_amount( sponsorship_get_all_ids( $f_bug_id ) ) > 0; if ( $t_bug_sponsored ) { if ( !access_has_bug_level( config_get( 'assign_sponsored_bugs_threshold' ), $f_bug_id ) ) { trigger_error( ERROR_SPONSORSHIP_ASSIGNER_ACCESS_LEVEL_TOO_LOW, ERROR ); } } if ( $f_handler_id != NO_USER ) { if ( !access_has_bug_level( config_get( 'handle_bug_threshold' ), $f_bug_id, $f_handler_id ) ) { trigger_error( ERROR_HANDLER_ACCESS_TOO_LOW, ERROR ); } if ( $t_bug_sponsored ) { if ( !access_has_bug_level( config_get( 'handle_sponsored_bugs_threshold' ), $f_bug_id, $f_handler_id ) ) { trigger_error( ERROR_SPONSORSHIP_HANDLER_ACCESS_LEVEL_TOO_LOW, ERROR ); } } } } $t_status_label = str_replace( " ", "_", MantisEnum::getLabel( config_get( 'status_enum_string' ), $f_new_status ) ); html_page_top( bug_format_summary( $f_bug_id, SUMMARY_CAPTION ) ); print_recently_visited(); ?> <br /> <div align="center"> <form method="post" action="bug_update.php"> <?php echo form_security_field( 'bug_update' ) ?> <table class="width75" cellspacing="1"> <!-- Title --> <tr> <td class="form-title" colspan="2"> <input type="hidden" name="bug_id" value="<?php echo $f_bug_id ?>" /> <input type="hidden" name="status" value="<?php echo $f_new_status ?>" /> <?php echo lang_get( $t_status_label . '_bug_title' ) ?> </td> </tr> <?php if ( $t_resolved <= $f_new_status ) { if ( relationship_can_resolve_bug( $f_bug_id ) == false ) { echo "<tr><td colspan=\"2\">" . lang_get( 'relationship_warning_blocking_bugs_not_resolved_2' ) . "</td></tr>"; } } ?> <?php $t_current_resolution = $t_bug->resolution; $t_bug_is_open = in_array( $t_current_resolution, array( config_get( 'default_bug_resolution' ), config_get( 'bug_reopen_resolution' ) ) ); if ( ( $t_resolved <= $f_new_status ) && ( ( $t_closed > $f_new_status ) || ( $t_bug_is_open ) ) ) { ?> <!-- Resolution --> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <?php echo lang_get( 'resolution' ) ?> </td> <td> <select name="resolution"> <?php $t_resolution = $t_bug_is_open ? config_get( 'bug_resolution_fixed_threshold' ) : $t_current_resolution; print_enum_string_option_list( "resolution", $t_resolution ); ?> </select> </td> </tr> <?php } ?> <?php if ( ( $t_resolved <= $f_new_status ) && ( $t_closed > $f_new_status ) ) { ?> <!-- Duplicate ID --> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <?php echo lang_get( 'duplicate_id' ) ?> </td> <td> <input type="text" name="duplicate_id" maxlength="10" /> </td> </tr> <?php } ?> <?php if ( access_has_bug_level( config_get( 'update_bug_assign_threshold', config_get( 'update_bug_threshold' ) ), $f_bug_id ) ) { $t_suggested_handler_id = $t_bug->handler_id; if ( $t_suggested_handler_id == NO_USER && access_has_bug_level( config_get( 'handle_bug_threshold' ), $f_bug_id ) ) { $t_suggested_handler_id = $t_current_user_id; } ?> <!-- Assigned To --> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <?php echo lang_get( 'assigned_to' ) ?> </td> <td> <select name="handler_id"> <option value="0"></option> <?php print_assign_to_option_list( $t_suggested_handler_id, $t_bug->project_id ) ?> </select> </td> </tr> <?php } ?> <!-- Ask for Target Version in a list that contain only FUTURE versions (not released) --> <?php if ( config_get( 'ask_target_version' ) == ON ) { if ( ( $f_new_status == $t_confirmed) ) {?> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <?php echo lang_get( 'target_version' ) ?> </td> <td> <select name="target_version"> <?php print_version_option_list( $t_bug->target_version, $t_bug->project_id, VERSION_FUTURE, false,false ) ?> </select> </td> </tr> <?php } } ?> <?php if ( $t_can_update_due_date ) { $t_date_to_display = ''; if ( !date_is_null( $t_bug->due_date ) ) { $t_date_to_display = date( config_get( 'calendar_date_format' ), $t_bug->due_date ); } ?> <!-- Due date --> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <?php print_documentation_link( 'due_date' ) ?> </td> <td> <?php print "<input ".helper_get_tab_index()." type=\"text\" id=\"due_date\" name=\"due_date\" size=\"20\" maxlength=\"16\" value=\"".$t_date_to_display."\" />"; date_print_calendar(); ?> </td> </tr> <?php } ?> <!-- Custom Fields --> <?php /** @todo thraxisp - I undid part of the change for #5068 for #5527 * We really need to say what fields are shown in which statusses. For now, * this page will show required custom fields in update mode, or * display or required fields on resolve or close */ $t_custom_status_label = "update"; # Don't show custom fields by default if ( ( $f_new_status == $t_resolved ) && ( $t_closed > $f_new_status ) ) { $t_custom_status_label = "resolved"; } if ( $t_closed == $f_new_status ) { $t_custom_status_label = "closed"; } $t_related_custom_field_ids = custom_field_get_linked_ids( $t_bug->project_id ); foreach( $t_related_custom_field_ids as $t_id ) { $t_def = custom_field_get_definition( $t_id ); $t_display = $t_def['display_' . $t_custom_status_label]; $t_require = $t_def['require_' . $t_custom_status_label]; if ( ( "update" == $t_custom_status_label ) && ( !$t_require ) ) { continue; } if ( in_array( $t_custom_status_label, array( "resolved", "closed" ) ) && !( $t_display || $t_require ) ) { continue; } if ( custom_field_has_write_access( $t_id, $f_bug_id ) ) { ?> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <?php if ( $t_require ) {?><span class="required">*</span><?php } echo lang_get_defaulted( $t_def['name'] ) ?> </td> <td> <?php print_custom_field_input( $t_def, $f_bug_id ); ?> </td> </tr> <?php } # custom_field_has_write_access( $t_id, $f_bug_id ) ) else if ( custom_field_has_read_access( $t_id, $f_bug_id ) ) { ?> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <?php echo lang_get_defaulted( $t_def['name'] ) ?> </td> <td> <?php print_custom_field_value( $t_def, $t_id, $f_bug_id ); ?> </td> </tr> <?php } # custom_field_has_read_access( $t_id, $f_bug_id ) ) } # foreach( $t_related_custom_field_ids as $t_id ) ?> <?php if ( ( $f_new_status >= $t_resolved ) ) { if ( version_should_show_product_version( $t_bug->project_id ) && !bug_is_readonly( $f_bug_id ) && access_has_bug_level( config_get( 'update_bug_threshold' ), $f_bug_id ) ) { ?> <!-- Fixed in Version --> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <?php echo lang_get( 'fixed_in_version' ) ?> </td> <td> <select name="fixed_in_version"> <?php print_version_option_list( $t_bug->fixed_in_version, $t_bug->project_id, VERSION_ALL ) ?> </select> </td> </tr> <?php } } ?> <?php if ( ( $f_new_status >= $t_resolved ) && ( $t_closed > $f_new_status ) ) { ?> <!-- Close Immediately (if enabled) --> <?php if ( ( ON == config_get( 'allow_close_immediately' ) ) && ( access_has_bug_level( access_get_status_threshold( $t_closed, $t_bug->project_id ), $f_bug_id ) ) ) { ?> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <?php echo lang_get( 'close_immediately' ) ?> </td> <td> <input type="checkbox" name="close_now" /> </td> </tr> <?php } ?> <?php } ?> <?php if ( ON == $f_reopen_flag ) { ?> <!-- Bug was re-opened --> <?php printf(" <input type=\"hidden\" name=\"resolution\" value=\"%s\" />\n", config_get( 'bug_reopen_resolution' ) ); } ?> <?php event_signal( 'EVENT_UPDATE_BUG_STATUS_FORM', array( $f_bug_id ) ); ?> <!-- Bugnote --> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <?php echo lang_get( 'add_bugnote_title' ) ?> </td> <td class="center"> <textarea name="bugnote_text" cols="80" rows="10"></textarea> </td> </tr> <?php if ( access_has_bug_level( config_get( 'private_bugnote_threshold' ), $f_bug_id ) ) { ?> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <?php echo lang_get( 'view_status' ) ?> </td> <td> <?php $t_default_bugnote_view_status = config_get( 'default_bugnote_view_status' ); if ( access_has_bug_level( config_get( 'set_view_status_threshold' ), $f_bug_id ) ) { ?> <input type="checkbox" name="private" <?php check_checked( $t_default_bugnote_view_status, VS_PRIVATE ); ?> /> <?php echo lang_get( 'private' ); } else { echo get_enum_element( 'project_view_state', $t_default_bugnote_view_status ); } ?> </td> </tr> <?php } ?> <?php if ( config_get('time_tracking_enabled') ) { ?> <?php if ( access_has_bug_level( config_get( 'private_bugnote_threshold' ), $f_bug_id ) ) { ?> <?php if ( access_has_bug_level( config_get( 'time_tracking_edit_threshold' ), $f_bug_id ) ) { ?> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <?php echo lang_get( 'time_tracking' ) ?> (HH:MM) </td> <td> <input type="text" name="time_tracking" size="5" value="0:00" /> </td> </tr> <?php } ?> <?php } ?> <?php } ?> <?php event_signal( 'EVENT_BUGNOTE_ADD_FORM', array( $f_bug_id ) ); ?> <!-- Submit Button --> <tr> <td class="center" colspan="2"> <input type="submit" class="button" value="<?php echo lang_get( $t_status_label . '_bug_button' ) ?>" /> </td> </tr> </table> </form> </div> <?php if ( $t_can_update_due_date ) { date_finish_calendar( 'due_date', 'trigger'); } echo '<br />'; include( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'bug_view_inc.php' ); bug_change_status_page_new.php (12,595 bytes)
<?php # MantisBT - a php based bugtracking system # MantisBT 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. # # MantisBT 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 MantisBT. If not, see <http://www.gnu.org/licenses/>. /** * @package MantisBT * @copyright Copyright (C) 2000 - 2002 Kenzaburo Ito - kenito@300baud.org * @copyright Copyright (C) 2002 - 2013 MantisBT Team - mantisbt-dev@lists.sourceforge.net * @link http://www.mantisbt.org */ /** * MantisBT Core API's */ $g_allow_browser_cache = 1; require_once( 'core.php' ); require_once( 'bug_api.php' ); require_once( 'custom_field_api.php' ); require_once( 'relationship_api.php' ); define ( 'BUG_VIEW_INC_ALLOW', true ); $f_bug_id = gpc_get_int( 'id' ); $t_bug = bug_get( $f_bug_id ); $tpl_file = __FILE__; $tpl_mantis_dir = dirname( __FILE__ ) . DIRECTORY_SEPARATOR; $tpl_show_page_header = false; $tpl_force_readonly = true; $tpl_fields_config_option = 'bug_change_status_page_fields'; 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; } $f_new_status = gpc_get_int( 'new_status' ); $f_reopen_flag = gpc_get_int( 'reopen_flag', OFF ); $t_reopen = config_get( 'bug_reopen_status', null, null, $t_bug->project_id ); $t_confirmed = config_get( 'bug_confirmed_status', null, null, $t_bug->project_id ); $t_resolved = config_get( 'bug_resolved_status_threshold', null, null, $t_bug->project_id ); $t_closed = config_get( 'bug_closed_status_threshold', null, null, $t_bug->project_id ); $t_current_user_id = auth_get_current_user_id(); # Ensure user has proper access level before proceeding if( $f_new_status == $t_reopen && $f_reopen_flag ) { access_ensure_can_reopen_bug( $t_bug, $t_current_user_id ); } else if( $f_new_status == $t_closed ) { access_ensure_can_close_bug( $t_bug, $t_current_user_id ); } else if ( bug_is_readonly( $f_bug_id ) || !access_has_bug_level( access_get_status_threshold( $f_new_status, $t_bug->project_id ), $f_bug_id, $t_current_user_id ) ) { access_denied(); } $t_can_update_due_date = access_has_bug_level( config_get( 'due_date_update_threshold' ), $f_bug_id ); # get new issue handler if set, otherwise default to original handler $f_handler_id = gpc_get_int( 'handler_id', $t_bug->handler_id ); if ( config_get( 'bug_assigned_status' ) == $f_new_status ) { $t_bug_sponsored = sponsorship_get_amount( sponsorship_get_all_ids( $f_bug_id ) ) > 0; if ( $t_bug_sponsored ) { if ( !access_has_bug_level( config_get( 'assign_sponsored_bugs_threshold' ), $f_bug_id ) ) { trigger_error( ERROR_SPONSORSHIP_ASSIGNER_ACCESS_LEVEL_TOO_LOW, ERROR ); } } if ( $f_handler_id != NO_USER ) { if ( !access_has_bug_level( config_get( 'handle_bug_threshold' ), $f_bug_id, $f_handler_id ) ) { trigger_error( ERROR_HANDLER_ACCESS_TOO_LOW, ERROR ); } if ( $t_bug_sponsored ) { if ( !access_has_bug_level( config_get( 'handle_sponsored_bugs_threshold' ), $f_bug_id, $f_handler_id ) ) { trigger_error( ERROR_SPONSORSHIP_HANDLER_ACCESS_LEVEL_TOO_LOW, ERROR ); } } } } $t_status_label = str_replace( " ", "_", MantisEnum::getLabel( config_get( 'status_enum_string' ), $f_new_status ) ); html_page_top( bug_format_summary( $f_bug_id, SUMMARY_CAPTION ) ); print_recently_visited(); ?> <br /> <div align="center"> <form method="post" action="bug_update.php"> <?php echo form_security_field( 'bug_update' ) ?> <table class="width75" cellspacing="1"> <!-- Title --> <tr> <td class="form-title" colspan="2"> <input type="hidden" name="bug_id" value="<?php echo $f_bug_id ?>" /> <input type="hidden" name="status" value="<?php echo $f_new_status ?>" /> <?php echo lang_get( $t_status_label . '_bug_title' ) ?> </td> </tr> <?php if ( $t_resolved <= $f_new_status ) { if ( relationship_can_resolve_bug( $f_bug_id ) == false ) { echo "<tr><td colspan=\"2\">" . lang_get( 'relationship_warning_blocking_bugs_not_resolved_2' ) . "</td></tr>"; } } ?> <?php $t_current_resolution = $t_bug->resolution; $t_bug_is_open = in_array( $t_current_resolution, array( config_get( 'default_bug_resolution' ), config_get( 'bug_reopen_resolution' ) ) ); if ( ( $t_resolved <= $f_new_status ) && ( ( $t_closed > $f_new_status ) || ( $t_bug_is_open ) ) ) { ?> <!-- Resolution --> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <?php echo lang_get( 'resolution' ) ?> </td> <td> <select name="resolution"> <?php $t_resolution = $t_bug_is_open ? config_get( 'bug_resolution_fixed_threshold' ) : $t_current_resolution; print_enum_string_option_list( "resolution", $t_resolution ); ?> </select> </td> </tr> <?php } ?> <?php if ( ( $t_resolved <= $f_new_status ) && ( $t_closed > $f_new_status ) ) { ?> <!-- Duplicate ID --> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <?php echo lang_get( 'duplicate_id' ) ?> </td> <td> <input type="text" name="duplicate_id" maxlength="10" /> </td> </tr> <?php } ?> <?php if ( access_has_bug_level( config_get( 'update_bug_assign_threshold', config_get( 'update_bug_threshold' ) ), $f_bug_id ) ) { $t_suggested_handler_id = $t_bug->handler_id; if ( $t_suggested_handler_id == NO_USER && access_has_bug_level( config_get( 'handle_bug_threshold' ), $f_bug_id ) ) { $t_suggested_handler_id = $t_current_user_id; } ?> <!-- Assigned To --> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <?php echo lang_get( 'assigned_to' ) ?> </td> <td> <select name="handler_id"> <option value="0"></option> <?php print_assign_to_option_list( $t_suggested_handler_id, $t_bug->project_id ) ?> </select> </td> </tr> <?php } ?> <!-- Update Target Version (only Future versions are displayed) --> <?php if ( access_has_bug_level( config_get( 'roadmap_update_threshold' ), $f_bug_id ) ) { ?> <?php if ( config_get( 'ask_target_version' ) == ON ) { if ( ( $f_new_status == $t_confirmed) ) {?> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <?php echo lang_get( 'target_version' ) ?> </td> <td> <select name="target_version"> <?php print_version_option_list( $t_bug->target_version, $t_bug->project_id, VERSION_FUTURE, false,false ) ?> </select> </td> </tr> <?php } } } ?> <?php if ( $t_can_update_due_date ) { $t_date_to_display = ''; if ( !date_is_null( $t_bug->due_date ) ) { $t_date_to_display = date( config_get( 'calendar_date_format' ), $t_bug->due_date ); } ?> <!-- Due date --> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <?php print_documentation_link( 'due_date' ) ?> </td> <td> <?php print "<input ".helper_get_tab_index()." type=\"text\" id=\"due_date\" name=\"due_date\" size=\"20\" maxlength=\"16\" value=\"".$t_date_to_display."\" />"; date_print_calendar(); ?> </td> </tr> <?php } ?> <!-- Custom Fields --> <?php /** @todo thraxisp - I undid part of the change for #5068 for #5527 * We really need to say what fields are shown in which statusses. For now, * this page will show required custom fields in update mode, or * display or required fields on resolve or close */ $t_custom_status_label = "update"; # Don't show custom fields by default if ( ( $f_new_status == $t_resolved ) && ( $t_closed > $f_new_status ) ) { $t_custom_status_label = "resolved"; } if ( $t_closed == $f_new_status ) { $t_custom_status_label = "closed"; } $t_related_custom_field_ids = custom_field_get_linked_ids( $t_bug->project_id ); foreach( $t_related_custom_field_ids as $t_id ) { $t_def = custom_field_get_definition( $t_id ); $t_display = $t_def['display_' . $t_custom_status_label]; $t_require = $t_def['require_' . $t_custom_status_label]; if ( ( "update" == $t_custom_status_label ) && ( !$t_require ) ) { continue; } if ( in_array( $t_custom_status_label, array( "resolved", "closed" ) ) && !( $t_display || $t_require ) ) { continue; } if ( custom_field_has_write_access( $t_id, $f_bug_id ) ) { ?> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <?php if ( $t_require ) {?><span class="required">*</span><?php } echo lang_get_defaulted( $t_def['name'] ) ?> </td> <td> <?php print_custom_field_input( $t_def, $f_bug_id ); ?> </td> </tr> <?php } # custom_field_has_write_access( $t_id, $f_bug_id ) ) else if ( custom_field_has_read_access( $t_id, $f_bug_id ) ) { ?> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <?php echo lang_get_defaulted( $t_def['name'] ) ?> </td> <td> <?php print_custom_field_value( $t_def, $t_id, $f_bug_id ); ?> </td> </tr> <?php } # custom_field_has_read_access( $t_id, $f_bug_id ) ) } # foreach( $t_related_custom_field_ids as $t_id ) ?> <?php if ( ( $f_new_status >= $t_resolved ) ) { if ( version_should_show_product_version( $t_bug->project_id ) && !bug_is_readonly( $f_bug_id ) && access_has_bug_level( config_get( 'update_bug_threshold' ), $f_bug_id ) ) { ?> <!-- Fixed in Version --> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <?php echo lang_get( 'fixed_in_version' ) ?> </td> <td> <select name="fixed_in_version"> <?php print_version_option_list( $t_bug->fixed_in_version, $t_bug->project_id, VERSION_ALL ) ?> </select> </td> </tr> <?php } } ?> <?php if ( ( $f_new_status >= $t_resolved ) && ( $t_closed > $f_new_status ) ) { ?> <!-- Close Immediately (if enabled) --> <?php if ( ( ON == config_get( 'allow_close_immediately' ) ) && ( access_has_bug_level( access_get_status_threshold( $t_closed, $t_bug->project_id ), $f_bug_id ) ) ) { ?> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <?php echo lang_get( 'close_immediately' ) ?> </td> <td> <input type="checkbox" name="close_now" /> </td> </tr> <?php } ?> <?php } ?> <?php if ( ON == $f_reopen_flag ) { ?> <!-- Bug was re-opened --> <?php printf(" <input type=\"hidden\" name=\"resolution\" value=\"%s\" />\n", config_get( 'bug_reopen_resolution' ) ); } ?> <?php event_signal( 'EVENT_UPDATE_BUG_STATUS_FORM', array( $f_bug_id ) ); ?> <!-- Bugnote --> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <?php echo lang_get( 'add_bugnote_title' ) ?> </td> <td class="center"> <textarea name="bugnote_text" cols="80" rows="10"></textarea> </td> </tr> <?php if ( access_has_bug_level( config_get( 'private_bugnote_threshold' ), $f_bug_id ) ) { ?> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <?php echo lang_get( 'view_status' ) ?> </td> <td> <?php $t_default_bugnote_view_status = config_get( 'default_bugnote_view_status' ); if ( access_has_bug_level( config_get( 'set_view_status_threshold' ), $f_bug_id ) ) { ?> <input type="checkbox" name="private" <?php check_checked( $t_default_bugnote_view_status, VS_PRIVATE ); ?> /> <?php echo lang_get( 'private' ); } else { echo get_enum_element( 'project_view_state', $t_default_bugnote_view_status ); } ?> </td> </tr> <?php } ?> <?php if ( config_get('time_tracking_enabled') ) { ?> <?php if ( access_has_bug_level( config_get( 'private_bugnote_threshold' ), $f_bug_id ) ) { ?> <?php if ( access_has_bug_level( config_get( 'time_tracking_edit_threshold' ), $f_bug_id ) ) { ?> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <?php echo lang_get( 'time_tracking' ) ?> (HH:MM) </td> <td> <input type="text" name="time_tracking" size="5" value="0:00" /> </td> </tr> <?php } ?> <?php } ?> <?php } ?> <?php event_signal( 'EVENT_BUGNOTE_ADD_FORM', array( $f_bug_id ) ); ?> <!-- Submit Button --> <tr> <td class="center" colspan="2"> <input type="submit" class="button" value="<?php echo lang_get( $t_status_label . '_bug_button' ) ?>" /> </td> </tr> </table> </form> </div> <?php if ( $t_can_update_due_date ) { date_finish_calendar( 'due_date', 'trigger'); } echo '<br />'; include( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . 'bug_view_inc.php' ); MandatoryFields.php (4,480 bytes)
<?php class MandatoryFieldsPlugin extends MantisPlugin { function register() { $this->name = 'MandatoryFilelds'; $this->description = 'Mandatory fields severity, projection'; $this->page = ''; $this->version = '1.0'; $this->requires = array( 'MantisCore' => '1.3.0', ); $this->author = 'carlos proensa'; } function hooks() { return array( 'EVENT_VIEW_BUG_DETAILS' => 'viewBugDetails', 'EVENT_UPDATE_BUG_STATUS_FORM' => 'updateBugStatusForm', 'EVENT_UPDATE_BUG_DATA' => 'updateBugData' ); } function updateBugStatusForm($p_event,$p_bug_id){ $f_bug = bug_get( $p_bug_id, false ); ?> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <span class="required">*</span><?php echo lang_get( 'severity' ) ?> </td> <td> <select name="severity"> <?php print_enum_string_option_list( 'severity', $f_bug->severity )?> </select> </td> </tr> <tr <?php echo helper_alternate_class() ?>> <td class="category"> <span class="required">*</span><?php echo lang_get( 'projection' ) ?> </td> <td> <select name="projection"> <?php print_enum_string_option_list( 'projection', $f_bug->projection ) ?> </select> </td> </tr> <?php } function updateBugData($p_event, $p_bug_upd_data, $p_bug_data){ if ( $p_bug_upd_data->status == RESOLVED ){ $t_severity= $p_bug_upd_data->severity; $t_projection= $p_bug_upd_data->projection; if ($t_severity == 0) { error_parameters(lang_get('severity')); trigger_error( ERROR_CUSTOM_FIELD_INVALID_VALUE, ERROR ); } if ($t_projection == 0) { error_parameters(lang_get('projection')); trigger_error( ERROR_CUSTOM_FIELD_INVALID_VALUE, ERROR ); } } return $p_bug_upd_data; } # # Evento al escribir la pagina de view_bug, para escrbir informacion extra # function viewBugDetails($p_event, $p_bug_id){ $f_bug = bug_get( $p_bug_id, false ); $f_user_id = auth_get_current_user_id(); $f_access_level = user_get_access_level($f_user_id, $f_bug->project_id); $f_severity = $f_bug->severity; $f_projection= $f_bug->projection; # # Muestra un aviso si falta rellenar campos de severity o projection # y si el usuario tiene permisos > informador # if ( $f_access_level > REPORTER && ($f_severity==0 || $f_projection==0) ){ $str= ''; $num_err= 0; if ($f_severity == 0) { $valid= false; $str= $str . lang_get( 'severity' ); $num_err++; } if ($f_projection == 0) { $valid= false; if ($num_err>0) $str= $str . ', '; $str= $str . lang_get( 'projection' ); $num_err++; } if ($num_err>1) $str = "Recuerde que los campos: $str, deben estar informados antes de resolver"; else $str = "Recuerde que el campo $str debe estar informado antes de resolver"; echo '<tr><td colspan="6">'; echo '<span style="color:red">' . $str . '</span>'; echo '</td></tr>'; } } } | ||||
Thanks for your contribution. Some hints: If you want a threshold ($g_bug_confirmed_status_threshold) you should check $f_new_status >= $t_confirmed You are not checking any access rights, thus the field will also be shown to users without rights to change this field. |
|
thank you for your feedback. access rights are now checked by the following line : "roadmap_update_threshold" already exists and is listed in "config_defaults_inc.php" as threshold for updating target_version The new "bug_change_status_page.php" is attached |
|
You should consider also the access checks which where used for "Fixed in Version" |
|
Can we merge this into one config variable? |
|
i.e. $g_bug_confirmed_status_threshold = CLOSED+9999999999 $g_ask_target_version = ON; Obviously, we need to work out how to add support for a new constant that represents "CLOSED+9999999999" I know on the side of access levels/users I did have some patches that try to merge some of the ON+EVERYBODY config's to just EVERYBODY (on the basis that NOBODY exists). If we had a similar NOSTATUS+EVERYSTATUS concept for status values we could do a similar config simplification exercise. Alternatively, we work on accepting this patch as is, then make merging/renaming/deprecating one of the config options a future change afterwards. |
|
But we are not talking about a threshold. We would need something like: $g_ask_target_version_on_status = STATUS_NONE to disable the functionality. A more generic approach would be to implement a status functionality similar to the access level functionality (Workflow Thresholds) |
|
nod - and thinking about it, you probably need that. For instance, on our bug tracker, we have 'acknowledged', 'confirmed' and 'assigned' - I'd probably be inclined to think that if you acknowledge an issue you probably are accepting that it exists, but don't know when/how/who is going to fix it. If you are confirming an issue or assigning and issue, that probably implies there's a good likelihood that you are going to target a fix - and straight away the scope of this patch does not allow that as you'd need to allow an array for target_status - hence, we probably need the "matrix" approach. |
|
Nice ! |
|
|
|
ok |
|
Hello dev team, could you please tell me if you plan to merge this PR into Mantis 1.3 ? Many thanks in advance for your feedback. |
|
PR 612 updated with Mantis 1.3.0-rc.2-dev code to reduce integration effort |
|
You are breaking some of our coding rules [1] and I am missing documentation in Administrators Guide. But wait with changing anything as there should be a discussion with other core team members if this approach makes sense in general. There must also be the discussion if this change should make it's way in 1.3.x. [1] https://www.mantisbt.org/wiki/doku.php/mantisbt:coding_guidelines |
|
Reminder sent to: cproensa, dregad, vboctor Thoughts? |
|
Hello, my thoughts: Also, if this functionality is implemented (for native fields), this also should be configurable per project, like custom fields are now. (*) If a plugin that can provide all this configuration and functionality is developed, i feel it would be a nice addition as a default plugin! In summary, i dont feel it's positive to integrate into master the functionality for only one field, and the method proposed is not clean enough to generalize on more fields. However, what is intended with this PR could be done with a plugin. |
|
Isn't it? |
|
you are right. I was parallelizing with custom fields functionality, where there is a manage page to easily configure "per project". |
|
We have to similar patterns:
They both are configs that take the set of fields that are to be displayed for a specific page. So instead of field to pages map, we have page to fields map. So for this case, I think we can do the following: Once we have this, we immediately get the customization that is required here. And for me I don't like that Close doesn't show duplicate_id field, but Resolve does. So if you want to set up a duplicate, you can't close directly. Now, once the above is in place, the override can happen in the database per project. We can also have a UI that control such config variables. We just have to be careful with the UI, since we typically had a lot of bugs trying to model the concept of global configs and overrides per project. We also have to make sure that when we are retrieving such configs we are passing the right config context that is based on the issue being updated and not current project for example. |
|
One thing I don't like about our pattern is that the customization of a page copies the list of all fields on that page and updates it. Hence, if a new field ever gets added to the default list of fields, it will be OFF by default. The good news is that we haven't done that forever. The approach recommended here is more friendly to addition of new default fields. Since the new field will have the default set of pages that it appears on, and hence the default intended behavior will be used. It is likely that this ship has sailed, but thought I would give both sides of the argument, though I'm not in favor of having two ways of doing such configuration. Changing the way we do it, may be painful for upgrades. So sticking with what we have should work. |
|
I'd like to see native fields and custom field go closer in capabilities. And... in that scenario, would it make sense to move the show/required options out from custom field management, and integrate them in this more general config schema? |
|
And for actuallly helping @Mr.Bricodage
I think your should try doing it with a plugin. That way you don't need to modify any code in mantis base, and your upgrade path is clean. See EVENT_UPDATE_BUG_STATUS_FORM to display fields on the status update form |
|
At we support custom_xyz in the field lists we use for column configuration options for View Issues, Print Issues, CSV, and Excel exports. So we already do support custom fields in such case the same way we support native fields. Users can select the set of fields to show, and in any order. However, we don't have the same for for the list of fields to show on different forms and we have a restriction of defining the order of custom fields relative to each other and only at the end of the list. I'm totally with you in providing a UI that enable controlling such configurations from the UI and treats custom fields and native fields the same way. So user can:
|
|
@cproensa : thank you for your sample plugin. That helped me a lot ;-) I attached the modified plugin I use in my company that answer to your needs. I didn't understand all responses provided above. I don't know if the attached solution is compliant with your Thoughts that seems to be more complex. I think that Mantis should display identically at least all versions fields (product_version, target_version, fixed_in_version). Regards |
|
attached : the same plugin for Mantis 1.3 |
|
What about Mantis 2.11 ? |
|