View Issue Details

IDProjectCategoryView StatusLast Update
0009039mantisbtfeaturepublic2014-11-07 16:19
Reporterprzemek7bc Assigned To 
PrioritynormalSeverityfeatureReproducibilityN/A
Status newResolutionopen 
Product Versiongit trunk 
Summary0009039: Tree model bug relations and custom bug status groups & workflows
Description

This patch provides:

  1. Custom bug status groups and workflows.
    You may define custom bug status groups (and workflows assigned to them). Then, from project create/edit page, you may choose which group should be used by the project.

  2. Tree model relations
    You may enable a project to use tree model relations. This allows you to display bug hierarchy path in "view issues" (column bug_path).
    Column bug_path may add one of two flags to a bug link:
    "!" - this bug is in an other project which does not support tree model bug relations,
    "~" - this bug creates a circular relation

I hope you will find those features useful and place them to svn.

TagsNo tags attached.
Attached Files
mantis-7bulls.com-patch.diff (14,185 bytes)   
Index: lang/strings_english.txt
===================================================================
--- lang/strings_english.txt	(wersja 5156)
+++ lang/strings_english.txt	(kopia robocza)
@@ -1511,4 +1511,12 @@
 # mind mapping
 $s_mindmap = 'Mindmap';
 $s_freemind_export = 'Freemind Export';
+
+# custom per project bug status groups
+$s_project_custom_bug_status_group = 'Select bug status group';
+$s_project_custom_bug_use_workflow = 'Use workflow';
+
+# tree model relationship
+$s_bug_path = 'Bug path';
+$s_enable_tree_model = 'Enable tree model bug relationship';
 ?>
\ brakuje znaku końca linii na końcu pliku 
Index: manage_proj_create_page.php
===================================================================
--- manage_proj_create_page.php	(wersja 5156)
+++ manage_proj_create_page.php	(kopia robocza)
@@ -102,6 +102,42 @@
 	</td>
 </tr>
 <?php } ?>
+
+<!-- Per project bug status groups -->
+<tr class="row-2">
+	<td class="category">
+		<?php echo lang_get('project_custom_bug_status_group'); ?>
+	</td>
+	<td>
+		<select name="per_project_bug_status">
+		<?php
+			$t_custom_classes_string = config_get('per_project_bug_status_enums');
+			if ($t_custom_classes_string == '') {
+				$t_custom_classes_enum = array();
+			} else {
+				$t_custom_classes_enum = get_enum_to_array($t_custom_classes_string);
+			}
+			echo '<option value="0">'.lang_get('select_option').'</option>';
+			foreach($t_custom_classes_enum as $t_idx => $t_name) {
+				echo "<option value=\"$t_idx\">".htmlspecialchars($t_name).'</option>';
+			}
+		?>
+		</select><br/>
+		<input type="checkbox" name="use_workflow" />
+		<?php echo lang_get('project_custom_bug_use_workflow'); ?>
+	</td>
+</tr>
+
+<!-- Per project tree model bug relationship -->
+<tr class="row-2">
+	<td class="category">
+		<?php echo lang_get('enable_tree_model'); ?>
+	</td>
+	<td>
+		<input type="checkbox" name="enable_tree_model" <?php if (config_get('tree_model_relationships')) { echo ' checked="checked"'; } ?> />
+	</td>
+</tr>
+
 <?php
 	if ( config_get( 'allow_file_upload' ) ) {
 	?>
Index: manage_proj_update.php
===================================================================
--- manage_proj_update.php	(wersja 5156)
+++ manage_proj_update.php	(kopia robocza)
@@ -40,5 +40,39 @@
 
 	project_update( $f_project_id, $f_name, $f_description, $f_status, $f_view_state, $f_file_path, $f_enabled, $f_inherit_global );
 
+	# Per project bug status group
+	config_set("per_project_bug_status_selected", gpc_get_int("per_project_bug_status"), NO_USER, $f_project_id);
+	$f_workflow = gpc_get_bool('use_workflow', false);
+	if (gpc_get_int("per_project_bug_status")) {
+		# custom bug status group selected
+		$t_status_enum = 'per_project_bug_status_'.gpc_get_int("per_project_bug_status");
+		config_set("status_enum_string", config_get($t_status_enum.'_enum'), NO_USER, $f_project_id);
+		if ($f_workflow) {
+			config_set('status_enum_workflow', config_get($t_status_enum.'_workflow'), NO_USER, $f_project_id);
+			config_set('per_project_bug_status_workflow', 1, NO_USER, $f_project_id);
+		} else {
+			config_set('status_enum_workflow', array(), NO_USER, $f_project_id);
+			config_set('per_project_bug_status_workflow', 0, NO_USER, $f_project_id);
+		}
+	} else {
+		# use the default bug status group
+		config_set("status_enum_string", config_get('status_enum_string', null, null, 0), NO_USER, $f_project_id);
+		if ($f_workflow) {
+			config_set("status_enum_workflow", config_get('status_enum_workflow', null, null, 0), NO_USER, $f_project_id);
+			config_set('per_project_bug_status_workflow', 1, NO_USER, $f_project_id);
+		} else {
+			config_set("status_enum_workflow", array(), NO_USER, $f_project_id);
+			config_set('per_project_bug_status_workflow', 0, NO_USER, $f_project_id);
+		}
+	}
+	
+	# tree model bug relations
+	$t_enable_tree_model = gpc_get_bool('enable_tree_model');
+	if ($t_enable_tree_model) {
+		config_set('tree_model_relationships', 1, NO_USER, $f_project_id);
+	} else {
+		config_set('tree_model_relationships', 0, NO_USER, $f_project_id);
+	}
+	
 	print_header_redirect( 'manage_proj_page.php' );
 ?>
Index: config_defaults_inc.php
===================================================================
--- config_defaults_inc.php	(wersja 5156)
+++ config_defaults_inc.php	(kopia robocza)
@@ -1995,4 +1995,62 @@
 	# Enables or disables the mind mapping features including ability to export Freemind files and 
 	# in browser view of generated mindmaps.
 	$g_mindmap_enabled = ON;
+	
+	#################################
+	# Per project bug status groups
+	#################################
+	
+	# This feature enables you to choose per project custom bug status groups and
+	# workflows.
+	 
+	# Custom status groups enum.
+	# The value of each enum should be the title of the bug status group (probably in
+	# your own language).
+	# For each group, you should define the folowing config entries (where XX is the
+	# status group ID/index as defined in the enum):
+	# 1. $g_per_project_bug_status_XX_enum
+	#    With avaible status enum (like in $g_status_enum_string).
+	#    If you define a custom status, you should also create a language code for it
+	#    or you will recieve a lot of errors in mantis (for the language your mantis
+	#    installation is using).
+	# 2. $g_per_project_bug_status_XX_workflow
+	#    You should define here a valid workflow (like in $g_status_enum_workflow)
+	#    or set it to array();
+	#
+	# Example:
+	#    $g_per_project_bug_status_enums = '10:Simple (new/acknowledged/resolved/closed)';
+	#    $g_per_project_bug_status_10_enum = '10:new,30:acknowledged,80:resolved,90:closed';
+	#    $g_per_project_bug_status_10_workflow = array(
+	#       NEW_ => '30:acknowledged',
+	#       ACKNOWLEDGED => '10:new,80:resolved',
+	#       RESOLVED => '30:acknowledged,90:closed',
+	#       CLOSED => '30:acknowledged'
+	#    );
+	$g_per_project_bug_status_enums = '';
+	
+	# Per project, selected bug status group.
+	# This config entry will be changed per project to specify which bug status group
+	# from the $g_per_project_bug_status_enums is select, or will stay blank for the
+	# default status group (from status_enum_string)
+	$g_per_project_bug_status_selected = '';
+	
+	# Per project, should a workflow be used with selected status group.
+	# This is a boolean flag, if set, current bug status group workflow will be assigned
+	# to status_enum_workflow.
+	$g_per_project_bug_status_workflow = '';
+
+
+	#############################
+	# Tree model relationships
+	#############################
+	
+	# If set to 1, this enables tree model relationships. In this mode. each bug may
+	# have only one "child of" relationship and circular relationships are detected
+	# and rejected.
+	# If this is enabled on an existing project with bugs with circular relationships,
+	# the first "child of" relation will be treated as valid, the other will be ignored. 
+	# 'tree_model_relationships' should be set to 0 if you have a project with complex 
+	# bug relationship model, and enable this only in the project that needs this.
+	$g_tree_model_relationships = 0;
+	
 ?>
\ brakuje znaku końca linii na końcu pliku 
Index: manage_proj_edit_page.php
===================================================================
--- manage_proj_edit_page.php	(wersja 5156)
+++ manage_proj_edit_page.php	(kopia robocza)
@@ -117,6 +117,48 @@
 	</td>
 </tr>
 
+<!-- Per project bug status groups -->
+<tr <?php echo helper_alternate_class() ?>>
+	<td class="category">
+		<?php echo lang_get('project_custom_bug_status_group'); ?>
+	</td>
+	<td>
+		
+		<select name="per_project_bug_status">
+		<?php
+			$t_cur_value = config_get("per_project_bug_status_selected", '', NULL, $f_project_id);
+			$t_custom_classes_string = config_get("per_project_bug_status_enums");
+			if ($t_custom_classes_string == '') {
+				$t_custom_classes_enum = array();
+			} else {
+				$t_custom_classes_enum = get_enum_to_array($t_custom_classes_string);
+			}
+			echo '<option value="0">'.lang_get('select_option').'</option>';
+			foreach($t_custom_classes_enum as $t_idx => $t_name) {
+				echo "<option value=\"$t_idx\""
+					.($t_idx == $t_cur_value ? ' selected="selected"' : '')
+					.'>'
+					.htmlspecialchars($t_name).'</option>';
+			}
+		?>
+		</select><br/>
+		<?php $t_useWorkflow = config_get('per_project_bug_status_workflow', 0, NULL, $f_project_id); ?> 
+		<input type="checkbox" name="use_workflow" <?php if ($t_useWorkflow) echo 'checked="checked"'; ?>/>
+		<?php echo lang_get('project_custom_bug_use_workflow'); ?>
+	</td>
+</tr>
+
+<!-- Per project tree model bug relationship -->
+<tr <?php echo helper_alternate_class() ?>>
+	<td class="category">
+		<?php echo lang_get('enable_tree_model'); ?>
+	</td>
+	<td>
+		<input type="checkbox" name="enable_tree_model" <?php if (config_get('tree_model_relationships', false, NULL, $f_project_id)) { echo ' checked="checked"'; } ?> />
+	</td>
+</tr>
+
+
 <!-- File upload path (if uploading is enabled) -->
 <?php if ( file_is_uploading_enabled() ) { ?>
 <tr <?php echo helper_alternate_class() ?>>
Index: core/columns_api.php
===================================================================
--- core/columns_api.php	(wersja 5156)
+++ core/columns_api.php	(kopia robocza)
@@ -56,6 +56,7 @@
 			'summary',
 			'version',
 			'view_state',
+			'bug_path',
 		);
 
 		# Add project custom fields to the array.  Only add the ones for which the current user has at least read access.
@@ -484,6 +485,14 @@
 
 	# --------------------
 	# $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
+	function print_column_title_bug_path( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
+		echo '<td>';
+		echo lang_get( 'bug_path' );
+		echo '</td>';
+	}
+
+	# --------------------
+	# $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 	function print_column_selection( $p_row, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 		global $t_checkboxes_exist, $t_update_bug_threshold;
 
@@ -782,4 +791,69 @@
 
 		echo '</td>';
 	}
+
+	# --------------------
+	# $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
+	function print_column_bug_path( $p_row, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
+		# stack of bugs, used to detect circular relations
+		$t_bug_stack = array();
+		# cache of projects using tree model bug relations
+		$t_tree_model_projects = array();
+		# array of bugs to display
+		$t_bugs = array();
+		# current bug Id.
+		$t_bug_id = $p_row['id'];
+		# current project Id.
+		$t_project_id = $p_row['project_id'];
+		
+		# check if this project use tree model
+		if (config_get('tree_model_relationships', false, null, $t_project_id)) {
+			$t_tree_model_projects[] = $t_project_id;
+		} else {
+			echo '<td class="left"></td>';
+			return;
+		}
+		
+		while ( 1 ) {
+				$t_relations = relationship_get_all_dest($t_bug_id);
+				$t_bug_id = null;
+				# get parent bug
+				foreach ($t_relations as $t_relationship) {
+					if ($t_relationship->type == 2) {
+						# only the first parent relation is considered valid
+						$t_bug_id = $t_relationship->src_bug_id;
+						$t_project_id = $t_relationship->src_project_id;
+					}
+				}
+				
+				if ($t_bug_id == null) {
+					# no parent bug
+					break; 
+				} else if (in_array($t_bug_id, $t_bug_stack)) {
+					# circular relation!
+					array_unshift($t_bugs, string_get_bug_view_link($t_bug_id).'~');
+					break;
+				}
+				
+				if (!in_array($t_project_id, $t_tree_model_projects)) {
+					if (config_get('tree_model_relationships', false, null, $t_project_id)) {
+						$t_tree_model_projects[] = $t_project_id;	
+					} else {
+						# this project doesn't support tree model bug relations
+						array_unshift($t_bugs, string_get_bug_view_link($t_bug_id).'!');
+						break;
+					}
+				}
+				
+				# add bug to the path
+				array_unshift($t_bugs, string_get_bug_view_link($t_bug_id));
+				$t_bug_stack[] = $t_bug_id;
+		}
+		
+		# generate path string to display
+		$t_path = implode(' <strong>/</strong> ', $t_bugs);
+		
+		echo '<td class="left">', $t_path , '</td>';
+	}
+
 ?>
Index: manage_proj_create.php
===================================================================
--- manage_proj_create.php	(wersja 5156)
+++ manage_proj_create.php	(kopia robocza)
@@ -54,6 +54,43 @@
 	if ( 0 != $f_parent_id ) {
 		project_hierarchy_add( $t_project_id, $f_parent_id, $f_inherit_parent );
 	}
+	
+	# Update per project bug status group
+	if ($t_project_id) {
+		config_set("per_project_bug_status_selected", gpc_get_int("per_project_bug_status"), NO_USER, $t_project_id);
+		$f_workflow = gpc_get_bool('use_workflow', false);
+		if (gpc_get_int("per_project_bug_status")) { //use_workflow
+			# use custom bug status group
+			$status_enum = 'per_project_bug_status_'.gpc_get_int("per_project_bug_status");
+			config_set("status_enum_string", config_get($status_enum.'_enum'), NO_USER, $t_project_id);
+			if ($f_workflow) {
+				config_set('status_enum_workflow', config_get($status_enum.'_workflow'), NO_USER, $t_project_id);
+				config_set('per_project_bug_status_workflow', 1, NO_USER, $t_project_id);
+			} else {
+				config_set('status_enum_workflow', array(), NO_USER, $t_project_id);
+				config_set('per_project_bug_status_workflow', 0, NO_USER, $t_project_id);
+			}
+		} else {
+			# use the default bug status group
+			config_set("status_enum_string", config_get('status_enum_string', null, null, 0), NO_USER, $t_project_id);
+			if ($f_workflow) {
+				config_set("status_enum_workflow", config_get('status_enum_workflow', null, null, 0), NO_USER, $t_project_id);
+				config_set('per_project_bug_status_workflow', 1, NO_USER, $t_project_id);
+			} else {
+				config_set("status_enum_workflow", array(), NO_USER, $t_project_id);
+				config_set('per_project_bug_status_workflow', 0, NO_USER, $t_project_id);
+			}
+		}
+	}
+	
+	# tree model bug relations
+	$t_enable_tree_model = gpc_get_bool('enable_tree_model');
+	if ($t_enable_tree_model) {
+		config_set('tree_model_relationships', 1, NO_USER, $t_project_id);
+	} else {
+		config_set('tree_model_relationships', 0, NO_USER, $t_project_id);
+	}
+	
 
 	$t_redirect_url = 'manage_proj_page.php';
 
mantis-7bulls.com-patch.diff (14,185 bytes)   
mantis-7bulls-tree-model-bug-relations.patch (19,542 bytes)   
Index: lang/strings_english.txt
===================================================================
--- lang/strings_english.txt	(wersja 5270)
+++ lang/strings_english.txt	(kopia robocza)
@@ -1525,4 +1525,13 @@
 #account_view_page.php
 $s_view_account_title = 'User Information';
 
+# custom per project bug status groups
+$s_project_custom_bug_status_group = 'Select bug status group';
+$s_project_custom_bug_use_workflow = 'Use workflow';
+
+# tree model relationship
+$s_bug_path = 'Bug path';
+$s_enable_tree_model = 'Enable tree model bug relationship';
+$s_parent_bug = 'Parent bug';
+
 ?>
\ brakuje znaku końca linii na końcu pliku 
Index: manage_proj_create_page.php
===================================================================
--- manage_proj_create_page.php	(wersja 5270)
+++ manage_proj_create_page.php	(kopia robocza)
@@ -102,6 +102,42 @@
 	</td>
 </tr>
 <?php } ?>
+
+<!-- Per project bug status groups -->
+<tr class="row-2">
+	<td class="category">
+		<?php echo lang_get('project_custom_bug_status_group'); ?>
+	</td>
+	<td>
+		<select name="per_project_bug_status">
+		<?php
+			$t_custom_classes_string = config_get('per_project_bug_status_enums');
+			if ($t_custom_classes_string == '') {
+				$t_custom_classes_enum = array();
+			} else {
+				$t_custom_classes_enum = get_enum_to_array($t_custom_classes_string);
+			}
+			echo '<option value="0">'.lang_get('select_option').'</option>';
+			foreach($t_custom_classes_enum as $t_idx => $t_name) {
+				echo "<option value=\"$t_idx\">".htmlspecialchars($t_name).'</option>';
+			}
+		?>
+		</select><br/>
+		<input type="checkbox" name="use_workflow" />
+		<?php echo lang_get('project_custom_bug_use_workflow'); ?>
+	</td>
+</tr>
+
+<!-- Per project tree model bug relations -->
+<tr class="row-2">
+	<td class="category">
+		<?php echo lang_get('enable_tree_model'); ?>
+	</td>
+	<td>
+		<input type="checkbox" name="enable_tree_model" <?php if (config_get('tree_model_relations')) { echo ' checked="checked"'; } ?> />
+	</td>
+</tr>
+
 <?php
 	if ( config_get( 'allow_file_upload' ) ) {
 	?>
Index: manage_proj_update.php
===================================================================
--- manage_proj_update.php	(wersja 5270)
+++ manage_proj_update.php	(kopia robocza)
@@ -40,5 +40,39 @@
 
 	project_update( $f_project_id, $f_name, $f_description, $f_status, $f_view_state, $f_file_path, $f_enabled, $f_inherit_global );
 
+	# Per project bug status group
+	config_set("per_project_bug_status_selected", gpc_get_int("per_project_bug_status"), NO_USER, $f_project_id);
+	$f_workflow = gpc_get_bool('use_workflow', false);
+	if (gpc_get_int("per_project_bug_status")) {
+		# custom bug status group selected
+		$t_status_enum = 'per_project_bug_status_'.gpc_get_int("per_project_bug_status");
+		config_set("status_enum_string", config_get($t_status_enum.'_enum'), NO_USER, $f_project_id);
+		if ($f_workflow) {
+			config_set('status_enum_workflow', config_get($t_status_enum.'_workflow'), NO_USER, $f_project_id);
+			config_set('per_project_bug_status_workflow', 1, NO_USER, $f_project_id);
+		} else {
+			config_set('status_enum_workflow', array(), NO_USER, $f_project_id);
+			config_set('per_project_bug_status_workflow', 0, NO_USER, $f_project_id);
+		}
+	} else {
+		# use the default bug status group
+		config_set("status_enum_string", config_get('status_enum_string', null, null, 0), NO_USER, $f_project_id);
+		if ($f_workflow) {
+			config_set("status_enum_workflow", config_get('status_enum_workflow', null, null, 0), NO_USER, $f_project_id);
+			config_set('per_project_bug_status_workflow', 1, NO_USER, $f_project_id);
+		} else {
+			config_set("status_enum_workflow", array(), NO_USER, $f_project_id);
+			config_set('per_project_bug_status_workflow', 0, NO_USER, $f_project_id);
+		}
+	}
+	
+	# tree model bug relations
+	$t_enable_tree_model = gpc_get_bool('enable_tree_model');
+	if ($t_enable_tree_model) {
+		config_set('tree_model_relations', 1, NO_USER, $f_project_id);
+	} else {
+		config_set('tree_model_relations', 0, NO_USER, $f_project_id);
+	}
+	
 	print_header_redirect( 'manage_proj_page.php' );
 ?>
Index: config_defaults_inc.php
===================================================================
--- config_defaults_inc.php	(wersja 5270)
+++ config_defaults_inc.php	(kopia robocza)
@@ -2018,4 +2018,64 @@
 	# Enables or disables the mind mapping features including ability to export Freemind files and 
 	# in browser view of generated mindmaps.
 	$g_mindmap_enabled = ON;
-?>
+	
+	#################################
+	# Per project bug status groups
+	#################################
+	
+	# This feature enables you to choose per project custom bug status groups and
+	# workflows.
+	 
+	# Custom status groups enum.
+	# The value of each enum should be the title of the bug status group (probably in
+	# your own language).
+	# For each group, you should define the folowing config entries (where XX is the
+	# status group ID/index as defined in the enum):
+	# 1. $g_per_project_bug_status_XX_enum
+	#    With avaible status enum (like in $g_status_enum_string).
+	#    If you define a custom status, you should also create a language code for it
+	#    or you will recieve a lot of errors in mantis (for the language your mantis
+	#    installation is using).
+	# 2. $g_per_project_bug_status_XX_workflow
+	#    You should define here a valid workflow (like in $g_status_enum_workflow)
+	#    or set it to array();
+	#
+	# Example:
+	#    $g_per_project_bug_status_enums = '10:Simple (new/acknowledged/resolved/closed)';
+	#    $g_per_project_bug_status_10_enum = '10:new,30:acknowledged,80:resolved,90:closed';
+	#    $g_per_project_bug_status_10_workflow = array(
+	#       NEW_ => '30:acknowledged',
+	#       ACKNOWLEDGED => '10:new,80:resolved',
+	#       RESOLVED => '30:acknowledged,90:closed',
+	#       CLOSED => '30:acknowledged'
+	#    );
+	$g_per_project_bug_status_enums = '';
+	
+	# Per project, selected bug status group.
+	# This config entry will be changed per project to specify which bug status group
+	# from the $g_per_project_bug_status_enums is select, or will stay blank for the
+	# default status group (from status_enum_string)
+	$g_per_project_bug_status_selected = '';
+	
+	# Per project, should a workflow be used with selected status group.
+	# This is a boolean flag, if set, current bug status group workflow will be assigned
+	# to status_enum_workflow.
+	$g_per_project_bug_status_workflow = '';
+
+
+	#############################
+	# Tree model relations
+	#############################
+	
+	# If set to 1, this enables tree model bug relations. In this mode. each bug may
+	# have only one "child of" relationship and circular relationships are detected
+	# and path generation is stopped (to keep compatibility with existing projects).
+	# If this is enabled on an existing project with bugs with circular relations,
+	# the first "child of" relation will be treated as valid, the other will be ignored.
+	# This may cause strange behaviour where "parent" column displays a different bug ID
+	# than "bug_path" column.
+	# 'tree_model_relations' should be set to 0 if you have a project with complex 
+	# bug relation model, and enable this only in the project that needs this.
+	$g_tree_model_relations = 0;
+	
+?>
\ brakuje znaku końca linii na końcu pliku 
Index: manage_proj_edit_page.php
===================================================================
--- manage_proj_edit_page.php	(wersja 5270)
+++ manage_proj_edit_page.php	(kopia robocza)
@@ -117,6 +117,48 @@
 	</td>
 </tr>
 
+<!-- Per project bug status groups -->
+<tr <?php echo helper_alternate_class() ?>>
+	<td class="category">
+		<?php echo lang_get('project_custom_bug_status_group'); ?>
+	</td>
+	<td>
+		
+		<select name="per_project_bug_status">
+		<?php
+			$t_cur_value = config_get("per_project_bug_status_selected", '', NULL, $f_project_id);
+			$t_custom_classes_string = config_get("per_project_bug_status_enums");
+			if ($t_custom_classes_string == '') {
+				$t_custom_classes_enum = array();
+			} else {
+				$t_custom_classes_enum = get_enum_to_array($t_custom_classes_string);
+			}
+			echo '<option value="0">'.lang_get('select_option').'</option>';
+			foreach($t_custom_classes_enum as $t_idx => $t_name) {
+				echo "<option value=\"$t_idx\""
+					.($t_idx == $t_cur_value ? ' selected="selected"' : '')
+					.'>'
+					.htmlspecialchars($t_name).'</option>';
+			}
+		?>
+		</select><br/>
+		<?php $t_useWorkflow = config_get('per_project_bug_status_workflow', 0, NULL, $f_project_id); ?> 
+		<input type="checkbox" name="use_workflow" <?php if ($t_useWorkflow) echo 'checked="checked"'; ?>/>
+		<?php echo lang_get('project_custom_bug_use_workflow'); ?>
+	</td>
+</tr>
+
+<!-- Per project tree model bug relationship -->
+<tr <?php echo helper_alternate_class() ?>>
+	<td class="category">
+		<?php echo lang_get('enable_tree_model'); ?>
+	</td>
+	<td>
+		<input type="checkbox" name="enable_tree_model" <?php if (config_get('tree_model_relations', false, NULL, $f_project_id)) { echo ' checked="checked"'; } ?> />
+	</td>
+</tr>
+
+
 <!-- File upload path (if uploading is enabled) -->
 <?php if ( file_is_uploading_enabled() ) { ?>
 <tr <?php echo helper_alternate_class() ?>>
Index: core/filter_api.php
===================================================================
--- core/filter_api.php	(wersja 5270)
+++ core/filter_api.php	(kopia robocza)
@@ -1136,6 +1136,7 @@
 				array_push( $t_where_clauses, "( $t_table_name.user_id=" . db_param($t_where_param_count++). " )" );
 			}
 		}
+				
 		# bug relationship
 		$t_any_found = false;
 		$c_rel_type = $t_filter['relationship_type'];
@@ -1305,7 +1306,7 @@
 				}
 			}
 		}
-
+		
 		$t_textsearch_where_clause = '';
 		$t_textsearch_wherejoin_clause = '';
 		# Simple Text Search - Thanks to Alan Knowles
@@ -1502,6 +1503,11 @@
 			}
 		}
 
+		# parent bug
+		$t_join.= " LEFT JOIN $t_bug_relationship_table AS parent_bug_table ON parent_bug_table.destination_bug_id=mantis_bug_table.id AND parent_bug_table.relationship_type=2";
+		array_push($t_select_clauses, 'parent_bug_table.source_bug_id AS parent_bug');
+		array_push($t_select_clauses, 'mantis_bug_table.summary AS summary_bug_path');
+		
 		# add basic sorting if necessary
 		if ( ! in_array( 'last_updated', $t_sort_fields ) ) {
 			$t_order_array[] = 'last_updated DESC';
@@ -1572,7 +1578,7 @@
 				$t_rows[] = bug_cache_database_result( $row, $t_stats[ $row['id'] ] );   
 			}			 
 		} 
-
+		
 		return $t_rows;
 	}
 
Index: core/columns_api.php
===================================================================
--- core/columns_api.php	(wersja 5270)
+++ core/columns_api.php	(kopia robocza)
@@ -56,6 +56,9 @@
 			'summary',
 			'version',
 			'view_state',
+			'bug_path',
+			'summary_bug_path',
+			'parent_bug',
 		);
 
 		# Add project custom fields to the array.  Only add the ones for which the current user has at least read access.
@@ -511,6 +514,32 @@
 
 	# --------------------
 	# $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
+	function print_column_title_bug_path( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
+		echo '<td>';
+		echo lang_get( 'bug_path' );
+		echo '</td>';
+	}
+
+	# --------------------
+	# $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
+	function print_column_title_summary_bug_path( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
+		echo '<td>';
+		print_view_bug_sort_link( lang_get( 'summary' ), 'summary_bug_path', $p_sort, $p_dir, $p_columns_target );
+		print_sort_icon( $p_dir, $p_sort, 'summary_bug_path' );
+		echo '</td>';
+	}
+	
+	# --------------------
+	# $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
+	function print_column_title_parent_bug( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
+		echo '<td>';
+		print_view_bug_sort_link( lang_get( 'parent_bug' ), 'parent_bug', $p_sort, $p_dir, $p_columns_target );
+		print_sort_icon( $p_dir, $p_sort, 'parent_bug' );
+		echo '</td>';
+	}
+	
+	# --------------------
+	# $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
 	function print_column_selection( $p_row, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
 		global $t_checkboxes_exist, $t_update_bug_threshold;
 
@@ -829,4 +858,165 @@
 
 		echo '</td>';
 	}
+
+	# --------------------
+	# $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
+	function print_column_bug_path( $p_row, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
+		# stack of bugs, used to detect circular relations
+		$t_bug_stack = array();
+		# cache of projects using tree model bug relations
+		$t_tree_model_projects = array();
+		# array of bugs to display
+		$t_bugs = array();
+		# current bug Id.
+		$t_bug_id = $p_row['id'];
+		# current project Id.
+		$t_project_id = $p_row['project_id'];
+		
+		# check if this project use tree model
+		if (config_get('tree_model_relations', false, null, $t_project_id)) {
+			$t_tree_model_projects[] = $t_project_id;
+		} else {
+			echo '<td class="left"></td>';
+			return;
+		}
+		
+		while ( 1 ) {
+				$t_relations = relationship_get_all_dest($t_bug_id);
+				$t_bug_id = null;
+				# get parent bug
+				foreach ($t_relations as $t_relationship) {
+					if ($t_relationship->type == 2) {
+						# only the first parent relation is considered valid
+						$t_bug_id = $t_relationship->src_bug_id;
+						$t_project_id = $t_relationship->src_project_id;
+					}
+				}
+				
+				if ($t_bug_id == null) {
+					# no parent bug
+					break; 
+				} else if (in_array($t_bug_id, $t_bug_stack)) {
+					# circular relation!
+					array_unshift($t_bugs, string_get_bug_view_link($t_bug_id).'~');
+					break;
+				}
+				
+				if (!in_array($t_project_id, $t_tree_model_projects)) {
+					if (config_get('tree_model_relations', false, null, $t_project_id)) {
+						$t_tree_model_projects[] = $t_project_id;	
+					} else {
+						# this project doesn't support tree model bug relations
+						array_unshift($t_bugs, string_get_bug_view_link($t_bug_id).'!');
+						break;
+					}
+				}
+				
+				# add bug to the path
+				array_unshift($t_bugs, string_get_bug_view_link($t_bug_id));
+				$t_bug_stack[] = $t_bug_id;
+		}
+		
+		# generate path string to display
+		$t_path = implode(' <strong>/</strong> ', $t_bugs);
+		
+		echo '<td class="left">', $t_path , '</td>';
+	}
+
+	# --------------------
+	# $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
+	function print_column_summary_bug_path( $p_row, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
+		global $t_icon_path;
+		# stack of bugs, used to detect circular relations
+		$t_bug_stack = array();
+		# cache of projects using tree model bug relations
+		$t_tree_model_projects = array();
+		# array of bugs to display
+		$t_bugs = array();
+		# current bug Id.
+		$t_bug_id = $p_row['id'];
+		# current project Id.
+		$t_project_id = $p_row['project_id'];
+		
+		# check if this project use tree model
+		if (config_get('tree_model_relations', false, null, $t_project_id)) {
+			$t_tree_model_projects[] = $t_project_id;
+	
+			while ( 1 ) {
+					$t_relations = relationship_get_all_dest($t_bug_id);
+					$t_bug_id = null;
+					# get parent bug
+					foreach ($t_relations as $t_relationship) {
+						if ($t_relationship->type == 2) {
+							# only the first parent relation is considered valid
+							$t_bug_id = $t_relationship->src_bug_id;
+							$t_project_id = $t_relationship->src_project_id;
+						}
+					}
+					
+					if ($t_bug_id == null) {
+						# no parent bug
+						break; 
+					} else if (in_array($t_bug_id, $t_bug_stack)) {
+						# circular relation!
+						array_unshift($t_bugs, string_get_bug_view_link($t_bug_id).'~');
+						break;
+					}
+					
+					if (!in_array($t_project_id, $t_tree_model_projects)) {
+						if (config_get('tree_model_relations', false, null, $t_project_id)) {
+							$t_tree_model_projects[] = $t_project_id;	
+						} else {
+							# this project doesn't support tree model bug relations
+							array_unshift($t_bugs, string_get_bug_view_link($t_bug_id).'!');
+							break;
+						}
+					}
+					
+					# add bug to the path
+					array_unshift($t_bugs, string_get_bug_view_link($t_bug_id));
+					$t_bug_stack[] = $t_bug_id;
+			}
+		}
+		
+		# generate path string to display
+		if (count($t_bugs)) {
+			$t_path = implode(' <strong>/</strong> ', $t_bugs);
+		} else {
+			$t_path = '';
+		}
+		
+		if ( $p_columns_target == COLUMNS_TARGET_CSV_PAGE ) {
+			$t_summary = string_attribute( $p_row['summary_bug_path'] );
+		} else {
+			$t_summary = string_display_line_links( $p_row['summary_bug_path'] );
+		}
+
+		echo '<td class="left">';
+		
+		if (strlen($t_path)) $t_path = '<small>'.$t_path.'</small> <strong>/</strong> ';
+		echo $t_path.$t_summary;
+		if ( VS_PRIVATE == $p_row['view_state'] ) {
+			printf( ' <img src="%s" alt="(%s)" title="%s" />'
+				, $t_icon_path . 'protected.gif'
+				, lang_get( 'private' )
+				, lang_get( 'private' )
+			);
+		}
+		echo '</td>';
+	}
+
+	# --------------------
+	# $p_columns_target: see COLUMNS_TARGET_* in constant_inc.php
+	function print_column_parent_bug( $p_row, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {
+		echo '<td>';
+		# bug's project Id.
+		$t_project_id = $p_row['project_id'];
+		if ($p_row['parent_bug'] && config_get('tree_model_relations', false, null, $t_project_id)) {
+			print_bug_link( $p_row['parent_bug'], false );
+		}
+		echo '</td>';
+	}
+
+	
 ?>
Index: manage_proj_create.php
===================================================================
--- manage_proj_create.php	(wersja 5270)
+++ manage_proj_create.php	(kopia robocza)
@@ -58,6 +58,43 @@
 	if ( 0 != $f_parent_id ) {
 		project_hierarchy_add( $t_project_id, $f_parent_id, $f_inherit_parent );
 	}
+	
+	# Update per project bug status group
+	if ($t_project_id) {
+		config_set("per_project_bug_status_selected", gpc_get_int("per_project_bug_status"), NO_USER, $t_project_id);
+		$f_workflow = gpc_get_bool('use_workflow', false);
+		if (gpc_get_int("per_project_bug_status")) { //use_workflow
+			# use custom bug status group
+			$status_enum = 'per_project_bug_status_'.gpc_get_int("per_project_bug_status");
+			config_set("status_enum_string", config_get($status_enum.'_enum'), NO_USER, $t_project_id);
+			if ($f_workflow) {
+				config_set('status_enum_workflow', config_get($status_enum.'_workflow'), NO_USER, $t_project_id);
+				config_set('per_project_bug_status_workflow', 1, NO_USER, $t_project_id);
+			} else {
+				config_set('status_enum_workflow', array(), NO_USER, $t_project_id);
+				config_set('per_project_bug_status_workflow', 0, NO_USER, $t_project_id);
+			}
+		} else {
+			# use the default bug status group
+			config_set("status_enum_string", config_get('status_enum_string', null, null, 0), NO_USER, $t_project_id);
+			if ($f_workflow) {
+				config_set("status_enum_workflow", config_get('status_enum_workflow', null, null, 0), NO_USER, $t_project_id);
+				config_set('per_project_bug_status_workflow', 1, NO_USER, $t_project_id);
+			} else {
+				config_set("status_enum_workflow", array(), NO_USER, $t_project_id);
+				config_set('per_project_bug_status_workflow', 0, NO_USER, $t_project_id);
+			}
+		}
+	}
+	
+	# tree model bug relations
+	$t_enable_tree_model = gpc_get_bool('enable_tree_model');
+	if ($t_enable_tree_model) {
+		config_set('tree_model_relations', 1, NO_USER, $t_project_id);
+	} else {
+		config_set('tree_model_relations', 0, NO_USER, $t_project_id);
+	}
+	
 
 	$t_redirect_url = 'manage_proj_page.php';
 

Activities

przemek7bc

przemek7bc

2008-05-05 10:04

reporter   ~0017776

Is this feature going to be included in Mantis ?

nico95

nico95

2008-05-07 07:32

reporter   ~0017789

What version of Mantis did you use ?
For me, with the 1.1.1, I don't find this part...

===================================================================
--- core/columns_api.php (wersja 5156)
+++ core/columns_api.php (kopia robocza)
@@ -56,6 +56,7 @@
'summary',
'version',
'view_state',

  • 'bug_path',
    );

    # Add project custom fields to the array.  Only add the ones for which the current user has at least read access.

As more, can you explain the implementation of a new status group and the use of the 'Use workflow' checkbox ?

Many thanks.

przemek7bc

przemek7bc

2008-05-07 09:32

reporter   ~0017790

I used svn head, but it was exactly a month ago, maybe new columns have been added.

Before you could create custom bug status or limit their number by editing per project configuration. Since my has a lot of projects, they wanted to define custom status groups once, and then use it in projects without editing any configuration by hand.

In Mantis, a workflow defines how a status may be changed for a bug (a list of all possible status transitions from each status). When you define a status group, you may also define a workflow for it. If 'Use workflow' is checked, that defined workflow will be used. If this checkbox is not set, workflows will be disabled.
This also works for the default status group and workflow.

I hope helps.

nico95

nico95

2008-05-13 06:21

reporter   ~0017820

Last edited: 2008-05-13 07:48

Can you put the "core/columns_api.php" file as joined file ?

thanks.

=> ok, I see the file in the SVN Head ...
I think I need to wait the next stable release to use this feature ...

przemek7bc

przemek7bc

2008-05-16 06:29

reporter   ~0017850

Sorry, I can't do that for the moment. My modified version core/columns_api.php now depends on some modifications in other files.

You may edit this file by hand. Add 'bug_path' to column list array (somewhere at the top of that file) and column drawing functions somewhere at the bottom:

  • function print_column_title_bug_path( $p_sort, $p_dir, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {

  • echo '<td>';

  • echo lang_get( 'bug_path' );

  • echo '</td>';

  • }

  • --------------------

  • $p_columns_target: see COLUMNSTARGET* in constant_inc.php

  • function print_column_bug_path( $p_row, $p_columns_target = COLUMNS_TARGET_VIEW_PAGE ) {

  • stack of bugs, used to detect circular relations

  • $t_bug_stack = array();

  • cache of projects using tree model bug relations

  • $t_tree_model_projects = array();

  • array of bugs to display

  • $t_bugs = array();

  • current bug Id.

  • $t_bug_id = $p_row['id'];

  • current project Id.

  • $t_project_id = $p_row['project_id'];

  • check if this project use tree model

  • if (config_get('tree_model_relationships', false, null, $t_project_id)) {

  • $t_tree_model_projects[] = $t_project_id;

  • } else {

  • echo '<td class="left"></td>';

  • return;

  • }

  • while ( 1 ) {

  • $t_relations = relationship_get_all_dest($t_bug_id);

  • $t_bug_id = null;

  • get parent bug

  • foreach ($t_relations as $t_relationship) {

  • if ($t_relationship->type == 2) {

  • only the first parent relation is considered valid

  • $t_bug_id = $t_relationship->src_bug_id;

  • $t_project_id = $t_relationship->src_project_id;

  • }

  • }

  • if ($t_bug_id == null) {

  • no parent bug

  • break;

  • } else if (in_array($t_bug_id, $t_bug_stack)) {

  • circular relation!

  • array_unshift($t_bugs, string_get_bug_view_link($t_bug_id).'~');

  • break;

  • }

  • if (!in_array($t_project_id, $t_tree_model_projects)) {

  • if (config_get('tree_model_relationships', false, null, $t_project_id)) {

  • $t_tree_model_projects[] = $t_project_id;

  • } else {

  • this project doesn't support tree model bug relations

  • array_unshift($t_bugs, string_get_bug_view_link($t_bug_id).'!');

  • break;

  • }

  • }

  • add bug to the path

  • array_unshift($t_bugs, string_get_bug_view_link($t_bug_id));

  • $t_bug_stack[] = $t_bug_id;

  • }

  • generate path string to display

  • $t_path = implode(' / ', $t_bugs);

  • echo '<td class="left">', $t_path , '</td>';

  • }

(remember to remove the + signs)

I will probably upgrade this patch soon, but I don't know if the mantis team will add this to svn.

giallu

giallu

2008-05-16 10:18

reporter   ~0017854

I am considering merging this in SVN (or at least recommend it...).
Could you please explain better what's the purpose and describe the implementation you've made, so the code review would be easier?

przemek7bc

przemek7bc

2008-05-16 10:57

reporter   ~0017855

There are two features in this patch

  1. custom bug status groups and workflows

  2. tree model bug relations

  3. Custom bug status groups and workflows.
    If you have some projects that should only have a limited number of status (like new, resolved and closed), you could change per project configuration by hand, or define a status group and assign it to the project from project create and edit page.

To define a status group, you write in the config_inc.php:

$g_per_project_bug_status_enums = '10:Simple new/resolved/closed)';
$g_per_project_bug_status_10_enum = '10:new,80:resolved,90:closed';

If you want a workflow for this group:
$g_per_project_bug_status_10workflow = array(
NEW
=> '80:resolved',
RESOLVED => '10:new,90:closed',
CLOSED => '80:resolved'
);

Then to assign this group, you edit your project and select a group from a dropdown list (optionaly enabling workflow).
When you save that project, workflow information will be saved to status_enum_workflow and status enum to status_enum_string. Since configuration may be written per project, no other project will be affected by this change.

  1. Tree model bug relations.
    To enable tree model relations, you must check a checkbox in project edit page. The value will be saved in per-project config key tree_model_relations.

There a 3 new columns:

  1. parent_bug
    Displays a link to the direct parent of this bug

  2. bug_path
    Displays the bug hierarchy path: 000123 / 000442 / 000456

  3. summary_bug_path
    Displays the bug hierarchy path and summary: 000123 / 000442 / 000456 / Something doesn't work

The tree model bug relations are disabled, parent_bug and bug_path are empty and summary_bug_path contains only the summary.

The patch I have posted here is outdated, I will post a new one on monday with the new columns.

przemek7bc

przemek7bc

2008-05-19 07:04

reporter   ~0017873

The new patch is here. It's made from svn head, so it should work without any problems.

giallu

giallu

2008-05-19 07:21

reporter   ~0017874

sorry for luring on this...

first things first: I think that, albeit related, if we are adding two features they should be submitted in two separate issues or, at least, two separate patches.

In the meanwhile, I'll try to apply the current patch locally and see how it works

thanks for your contribution