2014-11-28 15:19 EST

View Issue Details Jump to Notes ] Wiki ]
IDProjectCategoryView StatusLast Update
0003444mantisbtfeaturepublic2014-04-22 07:57
ReporterTomWalter 
Assigned To 
PrioritynormalSeverityfeatureReproducibilityN/A
StatusconfirmedResolutionopen 
Product Version 
Target VersionFixed in Version 
Summary0003444: Add user groups to streamline user management
DescriptionIt would be nice to have user groups, to which Access levels and Projects could be assigned, rather than assigning those things individually. For example in the case where you are tracking several projects from different clients, and each client has multiple users, and you want to be able to easily assign all the users from that client to the one project.
Tagsusergroups
Attached Files
  • diff file icon diff_from_RELEASE_0_18_3_20040512.diff (62,093 bytes) 2004-05-26 14:12 - 
    Index: bug_view_advanced_page.php
    ===================================================================
    RCS file: /cvsroot/mantisbt/mantisbt/bug_view_advanced_page.php,v
    retrieving revision 1.50
    diff -u -r1.50 bug_view_advanced_page.php
    --- bug_view_advanced_page.php	5 Feb 2004 12:45:19 -0000	1.50
    +++ bug_view_advanced_page.php	26 May 2004 18:12:52 -0000
    @@ -17,6 +17,7 @@
     	require_once( $t_core_path.'bug_api.php' );
     	require_once( $t_core_path.'custom_field_api.php' );
     	require_once( $t_core_path.'file_api.php' );
    +	require_once( $t_core_path.'group_api.php');
     	require_once( $t_core_path.'compress_api.php' );
     	require_once( $t_core_path.'date_api.php' );
     	require_once( $t_core_path.'relationship_api.php' );
    @@ -502,6 +503,98 @@
     
     	# User list monitoring the bug
     	include( $t_mantis_dir . 'bug_monitor_list_view_inc.php' );
    +	
    +		
    +?>
    +
    +<?php
    +if  ( access_has_global_level( DEVELOPER ) ) {
    +?>	
    +
    +<!-- USER GROUP MANAGEMENT (ADD) ( this really should be in a separate inc file ) -->
    +<br />
    +<div align="center">
    +	<form method="post" action="bug_group_add.php">
    +		<input type="hidden" name="bug_id" value="<?php echo $f_bug_id ?>" />
    +		<table class="width100" cellspacing="1">
    +			<tr>
    +				<td class="form-title" colspan="5">
    +					<?php echo lang_get( 'bug_add_group_title' ) ?>
    +				</td>
    +			</tr>
    +			<tr class="row-1" valign="top">
    +				<td class="category">
    +					<?php echo lang_get( 'groupname' ) ?>
    +				</td>
    +				<td>
    +					<select name="group_id[]" multiple size="3">
    +						<?php print_bug_group_list_option_list( $f_bug_id ) ?>
    +					</select>
    +				</td>
    +				<td>
    +					<input type="submit" value="<?php echo lang_get( 'add_group_button' ) ?>" />
    +				</td>
    +			</tr>
    +		</table>
    +	</form>
    +</div>
    +
    +
    +<br />
    +<div align="center">
    +	<table class="width100" cellspacing="1">
    +		<tr>
    +			<td class="form-title" colspan="4">
    +				<?php echo lang_get( 'manage_view_list_title' ) ?>
    +			</td>
    +		</tr>
    +		<tr class="row-category">
    +			<td>
    +				<?php echo lang_get( 'groupname' ) ?>
    +			</td>
    +			<td>
    +				<?php echo lang_get( 'access_level' ) ?>
    +			</td>
    +			<td class="center">
    +				<?php echo lang_get( 'actions' ) ?>
    +			</td>
    +		</tr>
    +<?php
    +	$t_groups = bug_get_all_group_rows( $f_bug_id );
    +	
    +	# reset the class counter
    +	helper_alternate_class( 0 );
    +
    +	foreach ( $t_groups as $t_group ) {
    +?>
    +		<tr <?php echo helper_alternate_class() ?> >
    +			<td>
    +				<?php echo $t_group['groupname'] ?>
    +			</td>
    +			<td>
    +				<?php echo get_enum_element( 'access_levels', $t_group['access_level'] ) ?>
    +			</td>
    +			<td class="center">
    +			<?php
    +				if ( access_has_global_level( DEVELOPER ) ) {
    +					if ( bug_includes_group( $f_bug_id, $t_group['id'] )  ) {
    +						print_bracket_link( 'bug_group_remove.php?bug_id=' . $f_bug_id . '&amp;group_id=' . $t_group['id'], lang_get( 'remove_link' ) );
    +					}
    +				}
    +			?>
    +			</td>
    +		</tr>
    +<?php
    +	}  # end for
    +?>
    +	</table>
    +</div>
    +<?php
    + } # end if
    +?>
    +
    +	
    +<?php
     
     	# Bugnotes
     	include( $t_mantis_dir . 'bugnote_add_inc.php' );
    Index: config_defaults_inc.php
    ===================================================================
    RCS file: /cvsroot/mantisbt/mantisbt/config_defaults_inc.php,v
    retrieving revision 1.145.2.1
    diff -u -r1.145.2.1 config_defaults_inc.php
    --- config_defaults_inc.php	12 May 2004 11:36:14 -0000	1.145.2.1
    +++ config_defaults_inc.php	26 May 2004 18:12:53 -0000
    @@ -841,6 +841,9 @@
     	$g_mantis_custom_field_table      	    = $g_db_table_prefix.'_custom_field_table';
     	$g_mantis_custom_field_string_table     = $g_db_table_prefix.'_custom_field_string_table';
     	$g_mantis_upgrade_table					= $g_db_table_prefix.'_upgrade_table';
    +	$g_mantis_group_table				    = $g_db_table_prefix.'_group_table';
    +	$g_mantis_group_user_list_table			= $g_db_table_prefix.'_group_user_list_table';
    +	$g_mantis_bug_group_list_table			= $g_db_table_prefix.'_bug_group_list_table';
     
     	###########################
     	# Mantis Enum Strings
    Index: core.php
    ===================================================================
    RCS file: /cvsroot/mantisbt/mantisbt/core.php,v
    retrieving revision 1.32
    diff -u -r1.32 core.php
    --- core.php	5 Feb 2004 01:17:13 -0000	1.32
    +++ core.php	26 May 2004 18:12:53 -0000
    @@ -102,4 +102,5 @@
     	require_once( $t_core_path.'print_api.php' );
     	require_once( $t_core_path.'helper_api.php' );
     	require_once( $t_core_path.'user_api.php' );
    +	require_once( $t_core_path.'group_api.php' );
     ?>
    Index: core/bug_api.php
    ===================================================================
    RCS file: /cvsroot/mantisbt/mantisbt/core/bug_api.php,v
    retrieving revision 1.50.2.1
    diff -u -r1.50.2.1 bug_api.php
    --- core/bug_api.php	10 May 2004 13:13:24 -0000	1.50.2.1
    +++ core/bug_api.php	26 May 2004 18:12:53 -0000
    @@ -698,6 +698,118 @@
     		
     		return db_result( $result );
     	}
    +	
    +	# --------------------
    +	# check to see if the bug_group combo already exists
    +	# returns true is duplicate is found, otherwise false
    +	function bug_includes_group( $p_bug_id, $p_group_id ) {
    +		$t_bug_group_list_table = config_get( 'mantis_bug_group_list_table' );
    +
    +		$c_bug_id	= db_prepare_int( $p_bug_id );
    +		$c_group_id	= db_prepare_int( $p_group_id );
    +
    +		$query = "SELECT COUNT(*)
    +				  FROM $t_bug_group_list_table
    +				  WHERE bug_id='$c_bug_id' AND
    +						group_id='$c_group_id'";
    +		$result = db_query( $query );
    +
    +		if ( 0 == db_result( $result ) ) {
    +			return false;
    +		} else {
    +			return true;
    +		}
    +	}
    +
    +	# --------------------
    +	# Returns a list of all groups that have view access to this bug
    +	function bug_get_group_view_list( $p_bug_id ) {
    +		$c_bug_id = db_prepare_int( $p_bug_id );
    +		
    +		$t_group_bug_list_table = config_get( 'mantis_group_bug_list_table' );
    +		
    +		$query = "SELECT group_id
    +				FROM $t_group_bug_list_table
    +				WHERE bug_id='$c_bug_id'
    +				ORDER BY group_id";
    +		$result = db_query( $query );
    +		
    +		return db_result( $result );
    +	}
    +
    +	# --------------------
    +	# return the descriptor holding all the info from the bug_group list
    +	# for the specified bug
    +	function bug_get_local_group_rows( $p_bug_id ) {
    +		$c_bug_id = db_prepare_int( $p_bug_id );
    +
    +		$t_bug_group_list_table = config_get( 'mantis_bug_group_list_table' );
    +
    +		$query = "SELECT *
    +				FROM $t_bug_group_list_table
    +				WHERE project_id='$c_bug_id'";
    +
    +		$result = db_query( $query );
    +
    +		$t_group_rows = array();
    +		$t_row_count = db_num_rows( $result );
    +
    +		for ( $i=0 ; $i < $t_row_count ; $i++ ) {
    +			array_push( $t_group_rows, db_fetch_array( $result ) );
    +		}
    +
    +		return $t_group_rows;
    +	}
    +
    +	# --------------------
    +	# Return an array of info about groups who have access to the the given bug
    +	# For each user we have 'id', 'groupname', and 'access_level' (overall access level)
    +	# If the second parameter is given, return only groups with an access level
    +	#  higher than the given value.
    +	function bug_get_all_group_rows( $p_bug_id  ) {
    +		$c_bug_id = db_prepare_int( $p_bug_id );
    +
    +		$t_group_table = config_get( 'mantis_group_table' );
    +		$t_bug_group_list_table = config_get( 'mantis_bug_group_list_table' );
    +
    +		$t_on = ON;
    +
    +		$t_access_level = ANYBODY;
    +
    +		if ( VS_PRIVATE == bug_get_field( $p_bug_id, 'view_state' ) ) {
    +			$t_access_level = max( $t_access_level, config_get( 'private_bug_threshold' ) );
    +		}
    +
    +		$t_access_clause = '';
    +
    +		if ( $t_access_level > 0 ) {
    +			$t_access_clause = ' AND access_level >= ' . $t_access_level;
    +		}
    +
    +		$t_groups = array();
    +
    +		// Get the project overrides
    +		$query = "SELECT g.id, g.groupname, g.access_level
    +					FROM $t_bug_group_list_table l, $t_group_table g
    +					WHERE l.group_id = g.id
    +					  AND g.enabled = $t_on
    +					  AND l.bug_id = $c_bug_id
    +					ORDER BY g.groupname";
    +
    +		$result = db_query( $query );
    +		$t_row_count = db_num_rows( $result );
    +
    +		for ( $i=0 ; $i < $t_row_count ; $i++ ) {
    +			$row = db_fetch_array( $result );
    +
    +			if ( $row['access_level'] >= $t_access_level ) {
    +				$t_groups[$row['id']] = $row;
    +			}
    +		}
    +
    +		return multi_sort( array_values($t_groups), 'username' );
    +	}
    +	
     
     	#===================================
     	# Data Modification
    @@ -924,6 +1036,62 @@
     
     		return true;
     	}
    +	
    +	# --------------------
    +	# add group to a bug view list
    +	function bug_add_group( $p_bug_id, $p_group_id ) {
    +		$t_bug_group_list_table = config_get( 'mantis_bug_group_list_table' );
    +
    +		$c_bug_id	= db_prepare_int( $p_bug_id );
    +		$c_group_id	= db_prepare_int( $p_group_id );
    +
    +		$query = "INSERT
    +				  INTO $t_bug_group_list_table
    +				    ( bug_id, group_id )
    +				  VALUES
    +				    ( '$c_bug_id', '$c_group_id' )";
    +		
    +		db_query( $query );
    +
    +		# db_query errors on failure so:
    +		return true;
    +	}
    +	
    +	# --------------------
    +	# remove group from bug view list
    +	function bug_remove_group( $p_bug_id, $p_group_id ) {
    +		$t_bug_group_list_table = config_get( 'mantis_bug_group_list_table' );
    +
    +		$c_bug_id	= db_prepare_int( $p_bug_id );
    +		$c_group_id	= db_prepare_int( $p_group_id );
    +
    +		$query = "DELETE FROM $t_bug_group_list_table
    +				  WHERE bug_id='$c_bug_id' AND
    +						group_id='$c_group_id'";
    +
    +		db_query( $query );
    +
    +		# db_query errors on failure so:
    +		return true;
    +	}
    +
    +	# --------------------
    +	# delete all groups from the bug view list for a given bug
    +	# this is useful when deleting a bug
    +	function bug_remove_all_groups( $p_bug_id ) {
    +		$t_bug_group_list_table = config_get( 'mantis_bug_group_list_table' );
    +
    +		$c_bug_id	= db_prepare_int( $p_bug_id );
    +
    +		$query = "DELETE FROM $t_bug_group_list_table
    +				WHERE bug_id='$c_bug_id'";
    +
    +		db_query( $query );
    +
    +		# db_query errors on failure so:
    +		return true;
    +	}
    +	
     
     	#===================================
     	# Other
    Index: core/constant_inc.php
    ===================================================================
    RCS file: /cvsroot/mantisbt/mantisbt/core/constant_inc.php,v
    retrieving revision 1.10
    diff -u -r1.10 constant_inc.php
    --- core/constant_inc.php	11 Feb 2004 22:16:29 -0000	1.10
    +++ core/constant_inc.php	26 May 2004 18:12:54 -0000
    @@ -116,6 +116,9 @@
     
     	# no user
     	define( 'NO_USER',		0 );
    +	
    +	# no group
    +	define( 'NO_GROUP', 		0 );
     
     	# history constants
     	define( 'NORMAL_TYPE',					0 );
    @@ -194,6 +197,11 @@
     	define( 'ERROR_USER_NAME_INVALID',				805 );
     	define( 'ERROR_USER_DOES_NOT_HAVE_REQ_ACCESS',		806 );
     
    +	# ERROR_GROUP_*
    +	define( 'ERROR_GROUP_NAME_NOT_UNIQUE',			1700 );
    +	define( 'ERROR_GROUP_NOT_FOUND',			1701 );
    +	define( 'ERROR_GROUP_NAME_INVALID',			1705 );
    +
     	# ERROR_AUTH_*
     	define( 'ERROR_AUTH_INVALID_COOKIE',			900 );
     
    Index: core/html_api.php
    ===================================================================
    RCS file: /cvsroot/mantisbt/mantisbt/core/html_api.php,v
    retrieving revision 1.88
    diff -u -r1.88 html_api.php
    --- core/html_api.php	29 Feb 2004 09:07:45 -0000	1.88
    +++ core/html_api.php	26 May 2004 18:12:54 -0000
    @@ -464,12 +464,14 @@
     		}
     
     		$t_manage_user_page 		= 'manage_user_page.php';
    +		$t_manage_group_page		= 'manage_group_page.php';
     		$t_manage_project_menu_page = 'manage_proj_page.php';
     		$t_manage_custom_field_page = 'manage_custom_field_page.php';
     		$t_documentation_page 		= 'documentation_page.php';
     
     		switch ( $p_page ) {
     			case $t_manage_user_page				: $t_manage_user_page 				= ''; break;
    +			case $t_manage_group_page:	  $t_manage_group_page		= ''; break;
     			case $t_manage_project_menu_page: $t_manage_project_menu_page 	= ''; break;
     			case $t_manage_custom_field_page: $t_manage_custom_field_page 	= ''; break;
     			case $t_documentation_page		: $t_documentation_page 		= ''; break;
    @@ -477,6 +479,7 @@
     
     		echo '<br /><div align="center">';
     			print_bracket_link( $t_manage_user_page, lang_get( 'manage_users_link' ) );
    +			print_bracket_link( $t_manage_group_page, lang_get( 'manage_groups_link' ) );
     			print_bracket_link( $t_manage_project_menu_page, lang_get( 'manage_projects_link' ) );
     			print_bracket_link( $t_manage_custom_field_page, lang_get( 'manage_custom_field_link' ) );
     			print_bracket_link( $t_documentation_page, lang_get( 'documentation_link' ) );
    Index: core/print_api.php
    ===================================================================
    RCS file: /cvsroot/mantisbt/mantisbt/core/print_api.php,v
    retrieving revision 1.72
    diff -u -r1.72 print_api.php
    --- core/print_api.php	5 Feb 2004 01:17:13 -0000	1.72
    +++ core/print_api.php	26 May 2004 18:12:54 -0000
    @@ -697,6 +697,117 @@
     			PRINT $t_project_name.' ['.$t_access_level.'] ('.$t_view_state.') [<a class="small" href="manage_user_proj_delete.php?project_id='.$t_project_id.'&amp;user_id='.$p_user_id.'">'. lang_get( 'remove_link' ).'</a>]<br />';
     		}
     	}
    +	
    +	
    +	# --------------------
    +	# list of users that are NOT in the specified group and that are enabled
    +	function print_group_user_list_option_list( $p_group_id=null ) {
    +		global	$g_mantis_group_user_list_table, $g_mantis_user_table;
    +
    +		if ( null == $p_group_id ) {
    +			return;
    +		}
    +		$c_group_id = (integer)$p_group_id;
    +
    +		$t_adm = ADMINISTRATOR;
    +		$query = "SELECT DISTINCT u.id, u.username
    +				FROM $g_mantis_user_table u
    +				LEFT JOIN $g_mantis_group_user_list_table g
    +				ON g.user_id=u.id AND g.group_id='$c_group_id'
    +				WHERE u.access_level<$t_adm AND
    +					u.enabled = 1 AND
    +					g.user_id IS NULL AND
    +					u.access_level<'$t_adm'
    +				ORDER BY u.username";
    +		$result = db_query( $query );
    +		$category_count = db_num_rows( $result );
    +		for ($i=0;$i<$category_count;$i++) {
    +			$row = db_fetch_array( $result );
    +			$t_username = $row['username'];
    +			$t_user_id = $row['id'];
    +			PRINT "<option value=\"$t_user_id\">$t_username</option>";
    +		}
    +	}
    +	
    +	# --------------------
    +	# list of groups that a user is NOT in
    +	function print_group_user_list_option_list2( $p_user_id ) {
    +		global	$g_mantis_group_user_list_table, $g_mantis_group_table;
    +
    +		$c_user_id = db_prepare_int( $p_user_id );
    +
    +		$query = "SELECT DISTINCT g.id, g.groupname
    +				FROM $g_mantis_group_table g
    +				LEFT JOIN $g_mantis_group_user_list_table u
    +				ON g.id=u.group_id AND u.user_id='$c_user_id'
    +				WHERE g.enabled=1 AND
    +					u.user_id IS NULL
    +				ORDER BY g.groupname";
    +		$result = db_query( $query );
    +		$category_count = db_num_rows( $result );
    +		for ($i=0;$i<$category_count;$i++) {
    +			$row = db_fetch_array( $result );
    +			$t_group_name	= $row['groupname'];
    +			$t_user_id			= $row['id'];
    +			PRINT "<option value=\"$t_user_id\">$t_group_name</option>";
    +		}
    +	}
    +	# --------------------
    +	# list of groups that a user is NOT in
    +	function print_group_user_list( $p_user_id ) {
    +		global	$g_mantis_group_user_list_table, $g_mantis_group_table;
    +
    +		$c_user_id = db_prepare_int( $p_user_id );
    +
    +		$query = "SELECT DISTINCT g.id, g.groupname
    +				FROM $g_mantis_group_table g
    +				LEFT JOIN $g_mantis_group_user_list_table u
    +				ON g.id=u.group_id
    +				WHERE g.enabled=1 AND
    +					u.user_id='$c_user_id'
    +				ORDER BY g.groupname";
    +		$result = db_query( $query );
    +		$category_count = db_num_rows( $result );
    +		for ($i=0;$i<$category_count;$i++) {
    +			$row = db_fetch_array( $result );
    +			$t_group_id	= $row['id'];
    +			$t_group_name	= $row['groupname'];
    +			PRINT $t_group_name.' ['.$t_access_level.'] ('.$t_view_state.') [<a class="small" href="manage_user_proj_delete.php?project_id='.$t_project_id.'&amp;user_id='.$p_user_id.'">'. lang_get( 'remove_link' ).'</a>]<br />';
    +		}
    +	}
    +
    +	
    +	# --------------------
    +	# list of users that are NOT in the specified group and that are enabled
    +	function print_bug_group_list_option_list( $p_bug_id=null ) {
    +		global	$g_mantis_bug_group_list_table, $g_mantis_group_table;
    +
    +		if ( null == $p_bug_id ) {
    +			return;
    +		}
    +		$c_bug_id = (integer)$p_bug_id;
    +
    +		$t_adm = ADMINISTRATOR;
    +		$query = "SELECT DISTINCT u.id, u.groupname
    +				FROM $g_mantis_group_table u
    +				LEFT JOIN $g_mantis_bug_group_list_table g
    +				ON g.group_id=u.id AND g.bug_id='$c_bug_id'
    +				WHERE u.access_level<$t_adm AND
    +					u.enabled = 1 AND
    +					g.group_id IS NULL AND
    +					u.access_level<'$t_adm'
    +				ORDER BY u.groupname";
    +		$result = db_query( $query );
    +		$category_count = db_num_rows( $result );
    +		for ($i=0;$i<$category_count;$i++) {
    +			$row = db_fetch_array( $result );
    +			$t_groupname = $row['groupname'];
    +			$t_group_id = $row['id'];
    +			PRINT "<option value=\"$t_group_id\">$t_groupname</option>";
    +		}
    +	}
    +	
    +	
     
     	# --------------------
     	###########################################################################
    Index: lang/strings_english.txt
    ===================================================================
    RCS file: /cvsroot/mantisbt/mantisbt/lang/strings_english.txt,v
    retrieving revision 1.154
    diff -u -r1.154 strings_english.txt
    --- lang/strings_english.txt	22 Feb 2004 04:26:48 -0000	1.154
    +++ lang/strings_english.txt	26 May 2004 18:12:55 -0000
    @@ -203,6 +203,9 @@
     $MANTIS_ERROR[ERROR_VERSION_NOT_FOUND] = 'Version not found.';
     $MANTIS_ERROR[ERROR_USER_NAME_INVALID] = 'The username is invalid. Usernames may only contain letters, numbers, spaces, hyphens, and underscores.';
     $MANTIS_ERROR[ERROR_USER_DOES_NOT_HAVE_REQ_ACCESS] = 'User does not have required access level';
    +$MANTIS_ERROR[ERROR_GROUP_NAME_INVALID] = 'ERROR: The groupname is invalid.';
    +$MANTIS_ERROR[ERROR_GROUP_NOT_FOUND]  	= 'ERROR: The group was not found.';
    +$MANTIS_ERROR[ERROR_GROUP_NAME_NOT_UNIQUE]  = 'ERROR: The groupname is not unique.';
     
     $s_login_error = 'ERROR: your account may be disabled or the username/password you entered is incorrect.';
     $s_login_cookies_disabled = 'ERROR: Your browser either doesn\'t know how to handle cookies, or refuses to handle them.';
    @@ -532,6 +535,24 @@
     $s_last_visit = 'Last Visit';
     $s_edit_user_link = 'Edit User';
     
    +# manage_group_page.php 
    +$s_manage_groups_link = 'Manage Groups';
    +$s_manage_groups_title = 'Manage Groups';
    +$s_new_groups_title = 'New Groups';
    +$s_create_new_group_link = 'Create New Group';
    +$s_groupname = 'Groupname';
    +$s_update_group_button = 'Update Group';
    +$s_group_level = 'Group Level';
    +
    +# manage_group_create_page.php
    +$s_create_new_group_title = 'Create New Group';
    +$s_create_group_button = 'Create Group';
    +$s_group_add_user_title = 'Add User to Group';
    +
    +# manage_create_new_group.php
    +$s_created_group_part1 = 'Created group';
    +$s_created_group_part2 = 'with an access level of';
    +
     # manage_proj_add.php
     $s_project_added_msg = 'Project has been successfully added...';
     
    @@ -634,6 +655,14 @@
     $s_manage_user_protected_msg = 'Account protected. Access level and enabled protected. Otherwise, account has been updated...';
     $s_manage_user_updated_msg = 'Account successfully updated...';
     
    +# manage_group_page.php
    +$s_edit_group_title = 'Edit Group';
    +$s_delete_group_button = 'Delete Group';
    +
    +# manage_group_update.php
    +$s_manage_group_protected_msg = 'Group protected. Access level and enabled protected. Otherwise, account has been updated...';
    +$s_manage_group_updated_msg = 'Group successfully updated...';
    +
     # menu_inc.php
     $s_main_link = 'Main';
     $s_view_bugs_link = 'View Bugs';
    @@ -724,6 +753,12 @@
     # proj_user_update.php
     $s_updated_user_msg = 'Successfully updated user';
     
    +# bug_group_add
    +$s_bug_add_group_title = 'Add Group to View List';
    +$s_bug_group_list_title = 'Group View List';
    +$s_add_group_button = 'Add Group';
    +$s_manage_view_list_title = 'Manage View List';
    +
     # report_add.php
     $s_must_enter_category = 'You must select a category';
     $s_must_enter_severity = 'You must select a severity';
    Index: bug_group_add.php
    ===================================================================
    RCS file: bug_group_add.php
    diff -N bug_group_add.php
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ bug_group_add.php	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,25 @@
    +<?php
    +	# Mantis - a php based bugtracking system
    +	# Copyright (C) 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
    +	# Copyright (C) 2002 - 2003  Mantis Team   - mantisbt-dev@lists.sourceforge.net
    +	# This program is distributed under the terms and conditions of the GPL
    +	# See the README and LICENSE files for details
    +
    +	# --------------------------------------------------------
    +	# $Id: bug_group_add.php,v 1.1 2003/08/08 20:14:07 dwoods Exp $
    +	# --------------------------------------------------------
    +?>
    +<?php require_once( 'core.php' ) ?>
    +<?php
    +	$f_bug_id	= gpc_get_int( 'bug_id' );
    +	$f_group_id	= gpc_get_int_array( 'group_id', array() );
    +
    +	access_ensure_global_level( DEVELOPER );
    +
    +	# Add user(s) to the current group
    +	foreach( $f_group_id as $t_group_id ) {
    +		bug_add_group( $f_bug_id, $t_group_id );
    +	}
    +
    +	print_header_redirect( 'bug_view_advanced_page.php?bug_id=' . $f_bug_id );
    +?>
    Index: bug_group_remove.php
    ===================================================================
    RCS file: bug_group_remove.php
    diff -N bug_group_remove.php
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ bug_group_remove.php	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,22 @@
    +<?php
    +	# Mantis - a php based bugtracking system
    +	# Copyright (C) 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
    +	# Copyright (C) 2002 - 2003  Mantis Team   - mantisbt-dev@lists.sourceforge.net
    +	# This program is distributed under the terms and conditions of the GPL
    +	# See the README and LICENSE files for details
    +
    +	# --------------------------------------------------------
    +	# $Id: bug_group_remove.php,v 1.1 2003/08/08 20:14:22 dwoods Exp $
    +	# --------------------------------------------------------
    +?>
    +<?php require_once( 'core.php' ) ?>
    +<?php
    +	$f_bug_id	= gpc_get_int( 'bug_id' );
    +	$f_group_id	= gpc_get_int( 'group_id' );
    +
    +	access_ensure_project_level( DEVELOPER );
    +
    +	bug_remove_group( $f_bug_id, $f_group_id );
    +
    +	print_header_redirect( 'bug_view_advanced_page.php?bug_id=' . $f_bug_id );
    +?>
    Index: manage_group_create.php
    ===================================================================
    RCS file: manage_group_create.php
    diff -N manage_group_create.php
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ manage_group_create.php	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,60 @@
    +<?php
    +	# Mantis - a php based bugtracking system
    +	# Copyright (C) 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
    +	# Copyright (C) 2002 - 2003  Mantis Team   - mantisbt-dev@lists.sourceforge.net
    +	# This program is distributed under the terms and conditions of the GPL
    +	# See the README and LICENSE files for details
    +
    +	# --------------------------------------------------------
    +	# $Id: manage_group_create.php,v 1.1 2003/08/06 19:50:23 dwoods Exp $
    +	# --------------------------------------------------------
    +?>
    +<?php
    +	require_once( 'core.php' );
    +	
    +	$t_core_path = config_get( 'core_path' );
    +	
    +	require_once( $t_core_path.'email_api.php' );
    +	require_once( $t_core_path.'group_api.php' );
    +?>
    +<?php
    +	access_ensure_global_level( config_get( 'manage_user_threshold' ) );
    +
    +	$f_groupname	= gpc_get_string( 'groupname' );
    +	$f_access_level	= gpc_get_string( 'access_level' );
    +	$f_protected	= gpc_get_bool( 'protected' );
    +	$f_enabled	= gpc_get_bool( 'enabled' );
    +
    +	# check for empty username
    +	$f_groupname = trim( $f_groupname );
    +	if ( is_blank( $f_groupname ) ) {
    +		trigger_error( ERROR_EMPTY_FIELD, ERROR );
    +	}
    +
    +	# Check the name for validity here so we do it before promting to use a
    +	#  blank password (don't want to prompt the user if the process will fail
    +	#  anyway)
    +	group_ensure_name_valid( $f_groupname );
    +
    +	group_create( $f_groupname, $f_access_level, $f_protected, $f_enabled );
    +
    +	$t_redirect_url = 'manage_group_page.php';
    +
    +	html_page_top1();
    +
    +	html_meta_redirect( $t_redirect_url );
    +
    +	html_page_top2();
    +?>
    +
    +<br />
    +<div align="center">
    +<?php
    +	$t_access_level = get_enum_element( 'access_levels', $f_access_level );
    +	echo lang_get( 'created_group_part1' ) . ' <span class="bold">' . $f_groupname . '</span> ' . lang_get( 'created_group_part2' ) . ' <span class="bold">' . $t_access_level . '</span><br />';
    +
    +	print_bracket_link( $t_redirect_url, lang_get( 'proceed' ) );
    +?>
    +</div>
    +
    +<?php html_page_bottom1( __FILE__ ) ?>
    Index: manage_group_create_page.php
    ===================================================================
    RCS file: manage_group_create_page.php
    diff -N manage_group_create_page.php
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ manage_group_create_page.php	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,73 @@
    +<?php
    +	# Mantis - a php based bugtracking system
    +	# Copyright (C) 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
    +	# Copyright (C) 2002 - 2003  Mantis Team   - mantisbt-dev@lists.sourceforge.net
    +	# This program is distributed under the terms and conditions of the GPL
    +	# See the README and LICENSE files for details
    +
    +	# --------------------------------------------------------
    +	# $Id: manage_group_create_page.php,v 1.1 2003/08/06 19:50:55 dwoods Exp $
    +	# --------------------------------------------------------
    +?>
    +<?php require_once( 'core.php' ) ?>
    +<?php
    +	access_ensure_global_level( config_get( 'manage_user_threshold' ) );
    +
    +	html_page_top1();
    +	html_page_top2();
    +
    +	print_manage_menu( 'manage_group_create_page.php' );
    +?>
    +<br />
    +<div align="center">
    +<form method="post" action="manage_group_create.php">
    +<table class="width50" cellspacing="1">
    +<tr>
    +	<td class="form-title" colspan="2">
    +		<?php echo lang_get( 'create_new_group_title' ) ?>
    +	</td>
    +</tr>
    +<tr <?php echo helper_alternate_class() ?>>
    +	<td class="category" width="25%">
    +		<?php echo lang_get( 'groupname' ) ?>
    +	</td>
    +	<td width="75%">
    +		<input type="text" name="groupname" size="32" maxlength="32" />
    +	</td>
    +</tr>
    +<tr <?php echo helper_alternate_class() ?>>
    +	<td class="category">
    +		<?php echo lang_get( 'access_level' ) ?>
    +	</td>
    +	<td>
    +		<select name="access_level">
    +			<?php print_enum_string_option_list( 'access_levels', config_get( 'default_new_group_access_level' ) ) ?>
    +		</select>
    +	</td>
    +</tr>
    +<tr <?php echo helper_alternate_class() ?>>
    +	<td class="category">
    +		<?php echo lang_get( 'enabled' ) ?>
    +	</td>
    +	<td>
    +		<input type="checkbox" name="enabled" checked="checked" />
    +	</td>
    +</tr>
    +<tr <?php echo helper_alternate_class() ?>>
    +	<td class="category">
    +		<?php echo lang_get( 'protected' ) ?>
    +	</td>
    +	<td colspan="2">
    +		<input type="checkbox" name="protected" />
    +	</td>
    +</tr>
    +<tr>
    +	<td class="center" colspan="2">
    +		<input type="submit" value="<?php echo lang_get( 'create_group_button' ) ?>" />
    +	</td>
    +</tr>
    +</table>
    +</form>
    +</div>
    +
    +<?php html_page_bottom1( __FILE__ ) ?>
    Index: manage_group_edit_page.php
    ===================================================================
    RCS file: manage_group_edit_page.php
    diff -N manage_group_edit_page.php
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ manage_group_edit_page.php	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,187 @@
    +<?php
    +	# Mantis - a php based bugtracking system
    +	# Copyright (C) 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
    +	# Copyright (C) 2002 - 2003  Mantis Team   - mantisbt-dev@lists.sourceforge.net
    +	# This program is distributed under the terms and conditions of the GPL
    +	# See the README and LICENSE files for details
    +
    +	# --------------------------------------------------------
    +	# $Id: manage_group_edit_page.php,v 1.1 2003/08/06 19:50:55 dwoods Exp $
    +	# --------------------------------------------------------
    +?>
    +<?php 	require_once( 'core.php' ); ?>
    +
    +<?php
    +	access_ensure_global_level( config_get( 'manage_user_threshold' ) );
    +
    +	$f_group_id = gpc_get_int( 'group_id' );
    +
    +	$t_group = group_get_row( $f_group_id );
    +
    +	html_page_top1();
    +	html_page_top2();
    +
    +	print_manage_menu();
    +?>
    +
    +<br />
    +
    +
    +<!-- USER INFO -->
    +<div align="center">
    +<form method="post" action="manage_group_update.php">
    +<table class="width75" cellspacing="1">
    +<!-- Title -->
    +<tr>
    +	<td class="form-title" colspan="2">
    +		<input type="hidden" name="group_id" value="<?php echo $t_group['id'] ?>" />
    +		<?php echo lang_get( 'edit_group_title' ) ?>
    +	</td>
    +</tr>
    +
    +<!-- Groupname -->
    +<tr <?php echo helper_alternate_class( 1 ) ?>>
    +	<td class="category" width="30%">
    +		<?php echo lang_get( 'groupname' ) ?>:
    +	</td>
    +	<td width="70%">
    +		<input type="text" size="16" maxlength="32" name="groupname" value="<?php echo $t_group['groupname'] ?>" />
    +	</td>
    +</tr>
    +
    +<!-- Group Level -->
    +<tr <?php echo helper_alternate_class() ?>>
    +	<td class="category">
    +		<?php echo lang_get( 'group_level' ) ?>:
    +	</td>
    +	<td>
    +		<select name="access_level">
    +			<?php print_enum_string_option_list( 'access_levels', $t_group['access_level'] ) ?>
    +		</select>
    +	</td>
    +</tr>
    +
    +<!-- Enabled Checkbox -->
    +<tr <?php echo helper_alternate_class() ?>>
    +	<td class="category">
    +		<?php echo lang_get( 'enabled' ) ?>:
    +	</td>
    +	<td>
    +		<input type="checkbox" name="enabled" <?php check_checked( $t_group['enabled'], ON ); ?> />
    +	</td>
    +</tr>
    +
    +<!-- Protected Checkbox -->
    +<tr <?php echo helper_alternate_class() ?>>
    +	<td class="category">
    +		<?php echo lang_get( 'protected' ) ?>:
    +	</td>
    +	<td>
    +		<input type="checkbox" name="protected" <?php check_checked( $t_group['protected'], ON ); ?> />
    +	</td>
    +</tr>
    +
    +<!-- Submit Button -->
    +<tr>
    +	<td colspan="2" class="center">
    +		<input type="submit" value="<?php echo lang_get( 'update_group_button' ) ?>" />
    +	</td>
    +</tr>
    +</table>
    +</form>
    +</div>
    +
    +<br />
    +
    +
    +<!-- USER MANAGEMENT (ADD) -->
    +
    +<br />
    +<div align="center">
    +	<form method="post" action="manage_group_user_add.php">
    +		<input type="hidden" name="group_id" value="<?php echo $f_group_id ?>" />
    +		<table class="width75" cellspacing="1">
    +			<tr>
    +				<td class="form-title" colspan="5">
    +					<?php echo lang_get( 'group_add_user_title' ) ?>
    +				</td>
    +			</tr>
    +			<tr class="row-1" valign="top">
    +				<td class="category">
    +					<?php echo lang_get( 'username' ) ?>
    +				</td>
    +				<td>
    +					<select name="user_id[]" multiple size="10">
    +						<?php print_group_user_list_option_list( $f_group_id ) ?>
    +					</select>
    +				</td>
    +				<td>
    +					<input type="submit" value="<?php echo lang_get( 'add_user_button' ) ?>" />
    +				</td>
    +			</tr>
    +		</table>
    +	</form>
    +</div>
    +
    +
    +<!-- LIST OF USERS -->
    +<br />
    +<div align="center">
    +	<table class="width75" cellspacing="1">
    +		<tr>
    +			<td class="form-title" colspan="4">
    +				<?php echo lang_get( 'manage_groups_title' ) ?>
    +			</td>
    +		</tr>
    +		<tr class="row-category">
    +			<td>
    +				<?php echo lang_get( 'username' ) ?>
    +			</td>
    +			<td>
    +				<?php echo lang_get( 'email' ) ?>
    +			</td>
    +			<td>
    +				<?php echo lang_get( 'access_level' ) ?>
    +			</td>
    +			<td class="center">
    +				<?php echo lang_get( 'actions' ) ?>
    +			</td>
    +		</tr>
    +<?php
    +	$t_users = group_get_all_user_rows( $f_group_id );
    +
    +	# reset the class counter
    +	helper_alternate_class( 0 );
    +
    +	foreach ( $t_users as $t_user ) {
    +?>
    +		<tr <?php echo helper_alternate_class() ?>>
    +			<td>
    +				<?php echo $t_user['username'] ?>
    +			</td>
    +			<td>
    +			<?php 
    +				$t_email = user_get_email( $t_user['id'] );
    +				print_email_link( $t_email, $t_email );
    +			?>
    +			</td>
    +			<td>
    +				<?php echo get_enum_element( 'access_levels', $t_user['access_level'] ) ?>
    +			</td>
    +			<td class="center">
    +			<?php
    +				if ( access_has_global_level( config_get( 'manage_user_threshold' ) ) ) {
    +					if ( group_includes_user( $f_group_id, $t_user['id'] )  ) {
    +						print_bracket_link( 'manage_group_user_remove.php?group_id=' . $f_group_id . '&amp;user_id=' . $t_user['id'], lang_get( 'remove_link' ) );
    +					}
    +				}
    +			?>
    +			</td>
    +		</tr>
    +<?php
    +	}  # end for
    +?>
    +	</table>
    +</div>
    +
    +<?php html_page_bottom1( __FILE__ ) ?>
    Index: manage_group_page.php
    ===================================================================
    RCS file: manage_group_page.php
    diff -N manage_group_page.php
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ manage_group_page.php	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,173 @@
    +<?php
    +	# Mantis - a php based bugtracking system
    +	# Copyright (C) 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
    +	# Copyright (C) 2002 - 2003  Mantis Team   - mantisbt-dev@lists.sourceforge.net
    +	# This program is distributed under the terms and conditions of the GPL
    +	# See the README and LICENSE files for details
    +?>
    +<?php
    +	require_once( 'core.php' );
    +	
    +	$t_core_path = config_get( 'core_path' );
    +
    +	require_once( $t_core_path . 'icon_api.php' );
    +?>
    +<?php
    +	access_ensure_global_level( config_get( 'manage_user_threshold' ) );
    +
    +	$f_sort	= gpc_get_string( 'sort', 'username' );
    +	$f_dir	= gpc_get_string( 'dir', 'ASC' );
    +	$f_hide = gpc_get_bool( 'hide' );
    +	$f_save = gpc_get_bool( 'save' );
    +
    +	$t_cookie_name = config_get( 'manage_cookie' );
    +
    +	# set cookie values for hide, sort by, and dir
    +	if ( $f_save ) {
    +		$t_manage_string = $f_hide.':'.$f_sort.':'.$f_dir;
    +		gpc_set_cookie( $t_cookie_name, $t_manage_string, true );
    +	} else if ( !is_blank( gpc_get_cookie( $t_cookie_name, '' ) ) ) {
    +		$t_manage_arr = explode( ':', gpc_get_cookie( $t_cookie_name ) );
    +		$f_hide = $t_manage_arr[0];
    +
    +		if ( isset( $t_manage_arr[1] ) ) {
    +			$f_sort = $t_manage_arr[1];
    +		} else {
    +			$f_sort = 'username';
    +		}
    +
    +		if ( isset( $t_manage_arr[2] ) ) {
    +			$f_dir  = $t_manage_arr[2];
    +		} else {
    +			$f_dir = 'DESC';
    +		}
    +	}
    +
    +	# Clean up the form variables
    +	$c_sort = addslashes($f_sort);
    +
    +	if ($f_dir == 'ASC') {
    +		$c_dir = 'ASC';
    +	} else {
    +		$c_dir = 'DESC';
    +	}
    +
    +	if ($f_hide == 0) { # a 0 will turn it off
    +		$c_hide = 0;
    +	} else {            # anything else (including 'on') will turn it on
    +		$c_hide = 1;
    +	}
    +?>
    +<?php html_page_top1() ?>
    +<?php html_page_top2() ?>
    +
    +<?php print_manage_menu( 'manage_group_page.php' ) ?>
    +
    +<?php # New Groups Form BEGIN ?>
    +<?php
    +	$t_group_table = config_get( 'mantis_group_table' );
    +
    +	$days_old = 7;
    +	$query = "SELECT *
    +		FROM $t_group_table
    +		WHERE TO_DAYS(NOW()) - TO_DAYS(date_created) <= '$days_old'
    +		ORDER BY date_created DESC";
    +	$result = db_query( $query );
    +	$new_group_count = db_num_rows( $result );
    +?>
    +<br />
    +<table class="width100" cellspacing="1">
    +<tr>
    +	<td class="form-title">
    +		<?php echo lang_get( 'new_groups_title' ) ?> (<?php echo lang_get( '1_week_title' ) ?>) [<?php echo $new_group_count ?>]
    +	</td>
    +</tr>
    +<tr <?php echo helper_alternate_class() ?>>
    +	<td>
    +<?php
    +for ($i=0;$i<$new_group_count;$i++) {
    +	$row = db_fetch_array( $result );
    +	$t_groupname = $row['groupname'];
    +
    +	echo $t_groupname.' : ';
    +}
    +?>
    +	</td>
    +</tr>
    +</table>
    +<?php # New Accounts Form END ?>
    +
    +
    +<?php # Manage Form BEGIN ?>
    +<?php
    +	# Get the group data in $c_sort order
    +	$query = "SELECT *,  UNIX_TIMESTAMP(date_created) as date_created
    +			FROM $t_group_table
    +			ORDER BY '$c_sort' $c_dir";
    +
    +	$result = db_query($query);
    +	$group_count = db_num_rows( $result );
    +?>
    +<br />
    +<table class="width100" cellspacing="1">
    +<tr>
    +	<td class="form-title" colspan="5">
    +		<?php echo lang_get( 'manage_groups_title' ) ?> [<?php echo $group_count ?>]
    +		<?php print_bracket_link( 'manage_group_create_page.php', lang_get( 'create_new_group_link' ) ) ?>
    +	</td>
    +	<td class="center" colspan="2">
    +		<form method="post" action="manage_group_page.php">
    +		<input type="hidden" name="sort" value="<?php echo $c_sort ?>" />
    +		<input type="hidden" name="dir" value="<?php echo $c_dir ?>" />
    +		<input type="hidden" name="save" value="1" />
    +		<input type="checkbox" name="hide" value="1" <?php check_checked( $c_hide, 1 ); ?> /> <?php echo lang_get( 'hide_inactive' ) ?>
    +		<input type="submit" value="<?php echo lang_get( 'filter_button' ) ?>" />
    +		</form>
    +	</td>
    +</tr>
    +<tr class="row-category">
    +	<td>
    +		<?php print_manage_user_sort_link(  'manage_group_page.php', lang_get( 'groupname' ), 'groupname', $c_dir, $c_sort, $c_hide ) ?>
    +		<?php print_sort_icon( $c_dir, $c_sort, 'groupname' ) ?>
    +	</td>
    +	<td>
    +		<?php print_manage_user_sort_link(  'manage_group_page.php', lang_get( 'group_level' ), 'access_level', $c_dir, $c_sort, $c_hide ) ?>
    +		<?php print_sort_icon( $c_dir, $c_sort, 'access_level' ) ?>
    +	</td>
    +	<td>
    +		<?php print_manage_user_sort_link(  'manage_group_page.php', lang_get( 'enabled' ), 'enabled', $c_dir, $c_sort, $c_hide ) ?>
    +		<?php print_sort_icon( $c_dir, $c_sort, 'enabled' ) ?>
    +	</td>
    +	<td>
    +		<?php print_manage_user_sort_link(  'manage_group_page.php', lang_get( 'protected' ), 'protected', $c_dir, $c_sort, $c_hide ) ?>
    +		<?php print_sort_icon( $c_dir, $c_sort, 'protected' ) ?>
    +	</td>
    +	<td>
    +		<?php print_manage_user_sort_link(  'manage_group_page.php', lang_get( 'date_created' ), 'date_created', $c_dir, $c_sort, $c_hide ) ?>
    +		<?php print_sort_icon( $c_dir, $c_sort, 'date_created' ) ?>
    +	</td>
    +</tr>
    +<?php
    +	for ($i=0;$i<$group_count;$i++) {
    +		# prefix group data with g_
    +		$row = db_fetch_array($result);
    +		extract( $row, EXTR_PREFIX_ALL, 'g' );
    +
    +		$g_date_created  = date( config_get( 'normal_date_format' ), $g_date_created );
    +?>
    +<tr <?php echo helper_alternate_class( $i ) ?>>
    +	<td>
    +		<a href="manage_group_edit_page.php?group_id=<?php echo $g_id ?>"><?php echo $g_groupname ?></a>
    +	</td>
    +	<td><?php echo get_enum_element( 'access_levels', $g_access_level ) ?></td>
    +	<td><?php echo trans_bool( $g_enabled ) ?></td>
    +	<td><?php echo trans_bool( $g_protected ) ?></td>
    +	<td><?php echo $g_date_created ?></td>
    +</tr>
    +<?php
    +	}  # end for
    +?>
    +</table>
    +<?php # Manage Form END ?>
    +
    +<?php html_page_bottom1( __FILE__ ) ?>
    Index: manage_group_update.php
    ===================================================================
    RCS file: manage_group_update.php
    diff -N manage_group_update.php
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ manage_group_update.php	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,81 @@
    +<?php
    +	# Mantis - a php based bugtracking system
    +	# Copyright (C) 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
    +	# Copyright (C) 2002 - 2003  Mantis Team   - mantisbt-dev@lists.sourceforge.net
    +	# This program is distributed under the terms and conditions of the GPL
    +	# See the README and LICENSE files for details
    +?>
    +<?php
    +	require_once( 'core.php' );
    +?>
    +<?php
    +	access_ensure_global_level( config_get( 'manage_user_threshold' ) );
    +
    +	$f_protected	= gpc_get_bool( 'protected' );
    +	$f_enabled	= gpc_get_bool( 'enabled' );
    +	$f_groupname	= gpc_get_string( 'groupname', '' );
    +	$f_access_level	= gpc_get_int( 'access_level' );
    +	$f_group_id	= gpc_get_int( 'group_id' );
    +	
    +	$f_username	= trim( $f_groupname );
    +
    +	$t_old_groupname = group_get_field( $f_group_id, 'groupname' );
    +
    +	# check that the username is unique
    +	if ( $t_old_groupname != $f_groupname &&
    +		 false == group_is_name_unique( $f_groupname ) ) {
    +		trigger_error( ERROR_GROUP_NAME_NOT_UNIQUE, ERROR );
    +	}
    +
    +	$c_groupname	= db_prepare_string( $f_groupname );
    +	$c_protected	= db_prepare_bool( $f_protected );
    +	$c_enabled	= db_prepare_bool( $f_enabled );
    +	$c_group_id	= db_prepare_int( $f_group_id );
    +	$c_access_level	= db_prepare_int( $f_access_level );
    +
    +	$t_group_table = config_get( 'mantis_group_table' );
    +
    +	$t_old_protected = group_get_field( $f_group_id, 'protected' );
    +
    +	# if the group is already protected and the admin is not removing the
    +	#  protected flag then don't update the access level and enabled flag.
    +	#  If the group was unprotected or the protected flag is being turned off
    +	#  then proceed with a full update.
    +	if ( $f_protected && $t_old_protected ) {
    +	    $query = "UPDATE $t_group_table
    +	    		SET groupname='$c_groupname', protected='$c_protected'
    +	    		WHERE id='$c_group_id'";
    +	} else {
    +	    $query = "UPDATE $t_group_table
    +	    		SET groupname='$c_groupname', access_level='$c_access_level', 
    +				enabled='$c_enabled', protected='$c_protected'
    +	    		WHERE id='$c_group_id'";
    +	}
    +
    +    $result = db_query( $query );
    +    $t_redirect_url = 'manage_group_page.php';
    +?>
    +<?php html_page_top1() ?>
    +<?php
    +	if ( $result ) {
    +		html_meta_redirect( $t_redirect_url );
    +	}
    +?>
    +<?php html_page_top2() ?>
    +
    +<br />
    +<div align="center">
    +<?php
    +	if ( $f_protected && $t_old_protected ) {				# PROTECTED
    +		echo lang_get( 'manage_group_protected_msg' ) . '<br />';
    +	} else if ( $result ) {					# SUCCESS
    +		echo lang_get( 'operation_successful' ) . '<br />';
    +	} else {								# FAILURE
    +		print_sql_error( $query );
    +	}
    +
    +	print_bracket_link( $t_redirect_url, lang_get( 'proceed' ) );
    +?>
    +</div>
    +
    +<?php html_page_bottom1( __FILE__ ) ?>
    Index: manage_group_user_add.php
    ===================================================================
    RCS file: manage_group_user_add.php
    diff -N manage_group_user_add.php
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ manage_group_user_add.php	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,25 @@
    +<?php
    +	# Mantis - a php based bugtracking system
    +	# Copyright (C) 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
    +	# Copyright (C) 2002 - 2003  Mantis Team   - mantisbt-dev@lists.sourceforge.net
    +	# This program is distributed under the terms and conditions of the GPL
    +	# See the README and LICENSE files for details
    +
    +	# --------------------------------------------------------
    +	# $Id: manage_group_user_add.php,v 1.2 2003/08/08 20:13:01 dwoods Exp $
    +	# --------------------------------------------------------
    +?>
    +<?php require_once( 'core.php' ) ?>
    +<?php
    +	$f_group_id	= gpc_get_int( 'group_id' );
    +	$f_user_id	= gpc_get_int_array( 'user_id', array() );
    +
    +	access_ensure_global_level( config_get( 'manage_user_threshold' ) );
    +
    +	# Add user(s) to the current group
    +	foreach( $f_user_id as $t_user_id ) {
    +		group_add_user( $f_group_id, $t_user_id );
    +	}
    +
    +	print_header_redirect( 'manage_group_edit_page.php?group_id=' . $f_group_id );
    +?>
    Index: manage_group_user_remove.php
    ===================================================================
    RCS file: manage_group_user_remove.php
    diff -N manage_group_user_remove.php
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ manage_group_user_remove.php	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,27 @@
    +<?php
    +	# Mantis - a php based bugtracking system
    +	# Copyright (C) 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
    +	# Copyright (C) 2002 - 2003  Mantis Team   - mantisbt-dev@lists.sourceforge.net
    +	# This program is distributed under the terms and conditions of the GPL
    +	# See the README and LICENSE files for details
    +
    +	# --------------------------------------------------------
    +	# $Id: manage_group_user_remove.php,v 1.1 2003/08/06 19:50:55 dwoods Exp $
    +	# --------------------------------------------------------
    +?>
    +<?php require_once( 'core.php' ) ?>
    +<?php
    +	$f_group_id	= gpc_get_int( 'group_id' );
    +	$f_user_id	= gpc_get_int( 'user_id' );
    +
    +	# We should check both since we are in the group section and an
    +	#  admin might raise the first threshold and not realize they need
    +	#  to raise the second 
    +	# Eventually there will be separate access levels for managing groups
    +	access_ensure_project_level( config_get( 'manage_user_threshold' ) ); # group threshold
    +	access_ensure_project_level( config_get( 'manage_user_threshold' ) ); # user threshold
    +
    +	group_remove_user( $f_group_id, $f_user_id );
    +
    +	print_header_redirect( 'manage_group_edit_page.php?group_id=' . $f_group_id );
    +?>
    Index: core/group_api.php
    ===================================================================
    RCS file: core/group_api.php
    diff -N core/group_api.php
    --- /dev/null	1 Jan 1970 00:00:00 -0000
    +++ core/group_api.php	1 Jan 1970 00:00:00 -0000
    @@ -0,0 +1,606 @@
    +<?php
    +	# Mantis - a php based bugtracking system
    +	# Copyright (C) 2000 - 2002  Kenzaburo Ito - kenito@300baud.org
    +	# Copyright (C) 2002 - 2003  Mantis Team   - mantisbt-dev@lists.sourceforge.net
    +	# This program is distributed under the terms and conditions of the GPL
    +	# See the README and LICENSE files for details
    +
    +	# --------------------------------------------------------
    +	# $Id: group_api.php,v 1.2 2003/08/08 20:16:05 dwoods Exp $
    +	# --------------------------------------------------------
    +
    +	$t_core_dir = dirname( __FILE__ ).DIRECTORY_SEPARATOR;
    +	
    +	require_once( $t_core_dir . 'email_api.php' );
    +	require_once( $t_core_dir . 'ldap_api.php' );
    +
    +	###########################################################################
    +	# Group API
    +	###########################################################################
    +
    +	#===================================
    +	# Caching
    +	#===================================
    +
    +	#########################################
    +	# SECURITY NOTE: cache globals are initialized here to prevent them
    +	#   being spoofed if register_globals is turned on
    +	#
    +	$g_cache_group = array();
    +
    +	# --------------------
    +	# Cache a group row if necessary and return the cached copy
    +	#  If the second parameter is true (default), trigger an error
    +	#  if the group can't be found.  If the second parameter is
    +	#  false, return false if the group can't be found.
    +	function group_cache_row( $p_group_id, $p_trigger_errors=true) {
    +		global $g_cache_group;
    +
    +		$c_group_id = db_prepare_int( $p_group_id );
    +
    +		$t_group_table = config_get( 'mantis_group_table' );
    +
    +		if ( isset ( $g_cache_group[$c_group_id] ) ) {
    +			return $g_cache_group[$c_group_id];
    +		}
    +
    +		$query = "SELECT *
    +				  FROM $t_group_table
    +				  WHERE id='$c_group_id'";
    +		$result = db_query( $query );
    +
    +		if ( 0 == db_num_rows( $result ) ) {
    +			if ( $p_trigger_errors ) {
    +				trigger_error( ERROR_GROUP_NOT_FOUND, ERROR );
    +			} else {
    +				return false;
    +			}
    +		}
    +
    +		$row = db_fetch_array( $result );
    +
    +		$g_cache_group[$c_group_id] = $row;
    +
    +		return $row;
    +	}
    +
    +	# --------------------
    +	# Clear the group cache (or just the given id if specified)
    +	function group_clear_cache( $p_group_id = null ) {
    +		global $g_cache_group;
    +
    +		if ( null === $p_group_id ) {
    +			$g_cache_group = array();
    +		} else {
    +			$c_group_id = db_prepare_int( $p_group_id );
    +			unset( $g_cache_group[$c_group_id] );
    +		}
    +
    +		return true;
    +	}
    +
    +	#===================================
    +	# Boolean queries and ensures
    +	#===================================
    +
    +	# --------------------
    +	# check to see if group exists by id
    +	# return true if it does, false otherwise
    +	#
    +	# Use group_cache_row() to benefit from caching if called multiple times
    +	#  and because if the user does exist the data may well be wanted
    +	function group_exists( $p_group_id ) {
    +		$row = group_cache_row( $p_group_id, false );
    +
    +		if ( false === $row ) {
    +			return false;
    +		} else {
    +			return true;
    +		}
    +	}
    +
    +	# --------------------
    +	# check to see if group exists by id
    +	# if it doesn't exist then error
    +	#  otherwise let execution continue undisturbed
    +	function group_ensure_exists( $p_group_id ) {
    +		if ( ! group_exists( $p_group_id ) ) {
    +			trigger_error( ERROR_USER_NOT_FOUND, ERROR );
    +		}
    +	}
    +
    +	# --------------------
    +	# return true if the groupname is unique, false if there is already a group
    +	#  with that groupname
    +	function group_is_name_unique( $p_groupname ) {
    +		$c_groupname = db_prepare_string( $p_groupname );
    +
    +		$t_group_table = config_get( 'mantis_group_table' );
    +
    +		$query = "SELECT COUNT(*)
    +				  FROM $t_group_table
    +				  WHERE groupname='$c_groupname'";
    +
    +	    $result = db_query( $query );
    +
    +	    if ( db_result( $result ) > 0 ) {
    +			return false;
    +		} else {
    +			return true;
    +		}
    +	}
    +
    +	# --------------------
    +	# Check if the groupname is unique and trigger an ERROR if it isn't
    +	function group_ensure_name_unique( $p_groupname ) {
    +		if ( ! group_is_name_unique( $p_groupname ) ) {
    +			trigger_error( ERROR_USER_NAME_NOT_UNIQUE, ERROR );
    +		}
    +	}
    +
    +	# --------------------
    +	# Check if the groupname is a valid username (does not account for uniqueness)
    +	# Return true if it is, false otherwise
    +	function group_is_name_valid( $p_groupname ) {
    +		# The DB field is only 32 characters
    +		if ( strlen( $p_groupname ) > 32 ) {
    +			return false;	
    +		}
    +
    +		# Only allow a basic set of characters
    +		if ( 0 == preg_match( '/^\w+$/', $p_groupname ) ) {
    +			return false;
    +		}
    +
    +		# We have a valid groupname
    +		return true;
    +	}
    +
    +	# --------------------
    +	# Check if the groupname is a valid groupname (does not account for uniqueness)
    +	# Trigger an error if the username is not valid
    +	function group_ensure_name_valid( $p_groupname ) {
    +		if ( ! group_is_name_valid( $p_groupname ) ) {
    +			trigger_error( ERROR_USER_NAME_INVALID, ERROR );
    +		}
    +	}
    +
    +	# --------------------
    +	# return whether user is monitoring bug for the user id and bug id
    +	# -- NOT IMPLEMENTED YET --- dwoods
    +	/*
    +	function group_is_monitoring_bug( $p_group_id, $p_bug_id ) {
    +		$c_group_id	= db_prepare_int( $p_group_id );
    +		$c_bug_id	= db_prepare_int( $p_bug_id );
    +
    +		$t_bug_monitor_table = config_get( 'mantis_bug_monitor_table' );
    +
    +		$query = "SELECT COUNT(*)
    +				  FROM $t_bug_monitor_table
    +				  WHERE user_id='$c_group_id' AND bug_id='$c_bug_id'";
    +
    +		$result = db_query( $query );
    +
    +		if ( 0 == db_result( $result ) ) {
    +			return false;
    +		} else {
    +			return true;
    +		}
    +	}
    +	*/
    +
    +	# --------------------
    +	# return true if the user has access of ADMINISTRATOR or higher, false otherwise
    +	# --- NOT IMPLEMENTED YET --- dwoods
    +	/*
    +	function group_is_development( $p_group_id ) {
    +		$t_access_level = user_get_field( $p_group_id, 'access_level' );
    +
    +		if ( $t_access_level >= DEVELOPER ) {
    +			return true;
    +		} else {
    +			return false;
    +		}
    +	}
    +	*/
    +
    +	# --------------------
    +	# return true is the group account is protected, false otherwise
    +	function group_is_protected( $p_group_id ) {
    +		return ( ON == group_get_field( $p_group_id, 'protected' ) );
    +	}
    +
    +	# --------------------
    +	# Trigger an ERROR if the group is protected
    +	function group_ensure_unprotected( $p_group_id ) {
    +		if ( group_is_protected( $p_group_id ) ) {
    +			trigger_error( ERROR_PROTECTED_ACCOUNT, ERROR );
    +		}
    +	}
    +
    +	# --------------------
    +	# return true is the group is enabled, false otherwise
    +	function group_is_enabled( $p_group_id ) {
    +		return ( ON == group_get_field( $p_group_id, 'enabled' ) );
    +	}
    +
    +	#===================================
    +	# Creation / Deletion / Updating
    +	#===================================
    +
    +	# --------------------
    +	# Create a user.
    +	# returns false if error, the generated cookie string if ok
    +	function group_create( $p_groupname, $p_access_level=null, $p_protected=false, $p_enabled=true ) {
    +		if ( null === $p_access_level ) {
    +			$p_access_level = config_get( 'default_new_group_access_level');
    +		}
    +
    +		$c_groupname	= db_prepare_string( $p_groupname );
    +		$c_access_level	= db_prepare_int( $p_access_level );
    +		$c_protected	= db_prepare_bool( $p_protected );
    +		$c_enabled	= db_prepare_bool( $p_enabled );
    +
    +		group_ensure_name_valid( $p_groupname );
    +		group_ensure_name_unique( $p_groupname );
    +
    +		$t_seed = $p_username;
    +		$t_cookie_string	= auth_generate_unique_cookie_string( $t_seed );
    +
    +		$t_group_table 		= config_get( 'mantis_group_table' );
    +
    +		$query = "INSERT INTO $t_group_table
    +				    ( id, groupname, date_created, enabled, protected, 
    +				      access_level, cookie_string )
    +				  VALUES
    +				    ( null, '$c_groupname', NOW(), $c_enabled, $c_protected, 
    +				      $c_access_level, '$t_cookie_string')";
    +		db_query( $query );
    +
    +		return $t_cookie_string;
    +	}
    +
    +	# --------------------
    +	# delete agroup
    +	# returns true when the account was successfully deleted
    +	function group_delete( $p_group_id ) {
    +		$c_group_id = db_prepare_int($p_group_id);
    +
    +		group_ensure_unprotected( $p_group_id );
    +
    +		$t_group_table 			= config_get('mantis_group_table');
    +		$t_group_user_list_table 	= config_get('mantis_group_user_list_table');
    +
    +		# Remove account
    +		$query = "DELETE
    +				  FROM $t_group_table
    +				  WHERE id='$c_group_id'";
    +		db_query( $query );
    +
    +		$query = "DELETE
    +				  FROM $t_group_user_list_table
    +				  WHERE group_id='$c_group_id'";
    +		db_query( $query );
    +
    +		group_clear_cache( $p_group_id );
    +
    +		return true;
    +    }
    +
    +	#===================================
    +	# Data Access
    +	#===================================
    +
    +	# --------------------
    +	# get a group id from a groupname
    +	#  return false if the groupname does not exist
    +	function group_get_id_by_name( $p_groupname ) {
    +		$c_groupname = db_prepare_string( $p_groupname );
    +
    +		$t_group_table = config_get( 'mantis_group_table' );
    +
    +		$query = "SELECT id
    +				  FROM $t_group_table
    +				  WHERE groupname='$c_groupname'";
    +		$result = db_query( $query );
    +
    +		if ( 0 == db_num_rows( $result ) ) {
    +			return false;
    +		} else {
    +			return db_result( $result );
    +		}
    +	}
    +
    +	# --------------------
    +	# return all data associated with a particular group name
    +	#  return false if the groupname does not exist
    +	function group_get_row_by_name( $p_groupname ) {
    +		$t_group_id = group_get_id_by_name( $p_groupname );
    +
    +		if ( false === $t_group_id ) {
    +			return false;
    +		}
    +
    +		$row = group_get_row( $t_group_id );
    +
    +		return $row;
    +	}
    +
    +	# --------------------
    +	# return a group row
    +	function group_get_row( $p_group_id ) {
    +		return group_cache_row( $p_group_id );
    +	}
    +
    +	# --------------------
    +	# return the specified group field for the group id
    +	function group_get_field( $p_group_id, $p_field_name ) {
    +		if ( NO_GROUP == $p_group_id ) {
    +			trigger_error( 'group_get_field() for NO_GROUP', WARNING );
    +			return "@null@";
    +		}
    +
    +		$row = group_get_row( $p_group_id );
    +
    +		if ( isset( $row[$p_field_name] ) ) {
    +			return $row[$p_field_name];
    +		} else {
    +			trigger_error( ERROR_DB_FIELD_NOT_FOUND, WARNING );
    +			return '';
    +		}
    +	}
    +
    +	# --------------------
    +	# return the groupname or a string saying "group no longer exists"
    +	#  if the group does not exist
    +	function group_get_name( $p_group_id ) {
    +		$row = group_cache_row( $p_group_id, false );
    +
    +		if ( false == $row ) {
    +			return lang_get( 'prefix_for_deleted_groups' ) . (integer)$p_group_id;
    +		} else {
    +			return $row['groupname'];
    +		}
    +	}
    +
    +	# --------------------
    +	# return the groups's access level
    +	function group_get_access_level( $p_group_id ) {
    +		$t_access_level  = group_get_field( $p_group_id, 'access_level' );
    +
    +		return $t_access_level;
    +	}
    +	
    +	# --------------------
    +	# check to see if the user/group combo already exists
    +	# returns true is duplicate is found, otherwise false
    +	function group_includes_user( $p_group_id, $p_user_id ) {
    +		$t_group_user_list_table = config_get( 'mantis_group_user_list_table' );
    +
    +		$c_group_id	= db_prepare_int( $p_group_id );
    +		$c_user_id	= db_prepare_int( $p_user_id );
    +
    +		$query = "SELECT COUNT(*)
    +				  FROM $t_group_user_list_table
    +				  WHERE group_id='$c_group_id' AND
    +						user_id='$c_user_id'";
    +		$result = db_query( $query );
    +
    +		if ( 0 == db_result( $result ) ) {
    +			return false;
    +		} else {
    +			return true;
    +		}
    +	}
    +	
    +	# --------------------
    +	# Return an array of info about users who are part of the given group
    +	# For each user we have 'id', 'username', and 'access_level' (overall access level)
    +	# If the second parameter is given, return only users with an access level
    +	#  higher than the given value.
    +	function group_get_all_user_rows( $p_group_id, $p_access_level=ANYBODY ) {
    +		$c_group_id	= db_prepare_int( $p_group_id );
    +
    +		# Optimization when access_level is NOBODY
    +		if ( NOBODY == $p_access_level ) {
    +			return array();
    +		}
    +
    +		$t_user_table = config_get( 'mantis_user_table' );
    +		$t_group_user_list_table = config_get( 'mantis_group_user_list_table' );
    +
    +		$t_on = ON;
    +
    +		$t_access_level = $p_access_level;
    +
    +		$t_access_clause = '';
    +
    +		if ( $t_access_level > 0 ) {
    +			$t_access_clause = ' AND access_level >= ' . $t_access_level;
    +		}
    +
    +		$t_users = array();
    +
    +		$query = "SELECT id, username, access_level
    +					FROM $t_user_table
    +					WHERE enabled = $t_on
    +					  $t_access_clause
    +					ORDER BY username";
    +
    +		$result = db_query( $query );
    +		$t_row_count = db_num_rows( $result );
    +		for ( $i=0 ; $i < $t_row_count ; $i++ ) {
    +			$row = db_fetch_array( $result );
    +			$t_users[$row['id']] = $row;
    +		}
    +
    +		$query = "SELECT u.id, u.username
    +					FROM $t_group_user_list_table l, $t_user_table u
    +					WHERE l.user_id = u.id
    +					  AND u.enabled = $t_on
    +					  AND l.group_id = $c_group_id
    +					ORDER BY u.username";
    +
    +		$result = db_query( $query );
    +		$t_row_count = db_num_rows( $result );
    +		for ( $i=0 ; $i < $t_row_count ; $i++ ) {
    +			$row = db_fetch_array( $result );
    +			$f_access_level = $t_users[$row['id']]['access_level'];
    +			if ( $f_access_level >= $p_access_level ) {
    +				$t_users[$row['id']] = $row;
    +				$t_users[$row['id']]['access_level'] = $f_access_level;
    +			} else {
    +				# If user's overridden level is lower than required, so remove
    +				#  them from the list if they were previously there
    +				unset( $t_users[$row['id']] );
    +			}
    +		}
    +
    +		return multi_sort( array_values($t_users), 'username' );
    +	}
    +	
    +	# --------------------
    +	# Return an array of user_id's that belong to the given group, if their access
    +	# level is above the access given.
    +	function group_get_users( $p_group_id, $p_access_level=ANYBODY ) {
    +		$c_group_id	= db_prepare_int( $p_group_id );
    +
    +		# Optimization when access_level is NOBODY
    +		if ( NOBODY == $p_access_level ) {
    +			return array();
    +		}
    +
    +		$t_user_table = config_get( 'mantis_user_table' );
    +		$t_group_user_list_table = config_get( 'mantis_group_user_list_table' );
    +
    +		$t_on = ON;
    +
    +		$t_access_level = $p_access_level;
    +
    +		$t_access_clause = '';
    +
    +		if ( $t_access_level > 0 ) {
    +			$t_access_clause = ' AND access_level >= ' . $t_access_level;
    +		}
    +
    +		$t_users = array();
    +
    +		// Get the project overrides
    +		$query = "SELECT u.id, u.username
    +				FROM $t_group_user_list_table l, $t_user_table u
    +				WHERE l.user_id = u.id
    +				  AND u.enabled = $t_on
    +				  AND l.group_id = $c_group_id
    +				ORDER BY u.username";
    +
    +		$result = db_query( $query );
    +		$t_row_count = db_num_rows( $result );
    +		for ( $i=0 ; $i < $t_row_count ; $i++ ) {
    +			$row = db_fetch_array( $result );
    +			
    +			if ( $f_access_level >= $p_access_level ) {
    +				$t_users[$row['id']] = $row;
    +				array_push( $t_users, $row['id'] );
    +			}
    +		}
    +
    +		return $t_users;
    +	}
    +	
    +
    +	#===================================
    +	# Data Modification
    +	#===================================
    +	
    +	# --------------------
    +	# add user to a group
    +	function group_add_user( $p_group_id, $p_user_id ) {
    +		$t_group_user_list_table = config_get( 'mantis_group_user_list_table' );
    +
    +		$c_group_id	= db_prepare_int( $p_group_id );
    +		$c_user_id	= db_prepare_int( $p_user_id );
    +
    +		$query = "INSERT
    +				  INTO $t_group_user_list_table
    +				    ( group_id, user_id )
    +				  VALUES
    +				    ( '$c_group_id', '$c_user_id' )";
    +		
    +		db_query( $query );
    +
    +		# db_query errors on failure so:
    +		return true;
    +	}
    +	
    +	# --------------------
    +	# remove user from group
    +	function group_remove_user( $p_group_id, $p_user_id ) {
    +		$t_group_user_list_table = config_get( 'mantis_group_user_list_table' );
    +
    +		$c_group_id	= db_prepare_int( $p_group_id );
    +		$c_user_id	= db_prepare_int( $p_user_id );
    +
    +		$query = "DELETE FROM $t_group_user_list_table
    +				  WHERE group_id='$c_group_id' AND
    +						user_id='$c_user_id'";
    +
    +		db_query( $query );
    +
    +		# db_query errors on failure so:
    +		return true;
    +	}
    +
    +	# --------------------
    +	# delete all users from the group user list for a given group
    +	# this is useful when deleting a group
    +	function group_remove_all_users( $p_group_id ) {
    +		$t_group_user_list_table = config_get( 'mantis_group_user_list_table' );
    +
    +		$c_group_id	= db_prepare_int( $p_group_id );
    +
    +		$query = "DELETE FROM $t_group_user_list_table
    +				WHERE group_id='$c_group_id'";
    +
    +		db_query( $query );
    +
    +		# db_query errors on failure so:
    +		return true;
    +	}
    +
    +	# --------------------
    +	# Set a group field
    +	function group_set_field( $p_group_id, $p_field_name, $p_field_value ) {
    +		$c_group_id	= db_prepare_int( $p_group_id );
    +		$c_field_name	= db_prepare_string( $p_field_name );
    +		$c_field_value	= db_prepare_string( $p_field_value );
    +
    +		group_ensure_unprotected( $p_group_id );
    +
    +		$t_group_table = config_get( 'mantis_group_table' );
    +
    +		$query = "UPDATE $t_group_table
    +				  SET $c_field_name='$c_field_value'
    +				  WHERE id='$c_group_id'";
    +
    +		db_query( $query );
    +
    +		group_clear_cache( $p_group_id );
    +
    +		#db_query() errors on failure so:
    +		return true;
    +	}
    +	
    +	# --------------------
    +	# 
    +	
    +	# --------------------
    +	# Set the user's groupname to the given string after checking that it is valid
    +	function group_set_name( $p_group_id, $p_groupname ) {
    +		group_ensure_name_valid( $p_groupname );
    +		group_ensure_name_unique( $p_groupname );
    +
    +		return group_set_field( $p_group_id, 'groupname', $p_groupname );
    +	}
    +	
    +			
    +?>
    
    diff file icon diff_from_RELEASE_0_18_3_20040512.diff (62,093 bytes) 2004-05-26 14:12 + 
  • zip file icon group_new_files.zip (13,881 bytes) 2004-05-26 14:13
  • ? file icon group_tables.sql (1,080 bytes) 2004-05-26 14:13
  • zip file icon usergroups_diff_from_0_19_CVS_20040529.zip (29,830 bytes) 2004-09-05 18:03
  • pdf file icon Creating groups in Mantis.pdf (92,496 bytes) 2009-10-09 04:55

- Relationships
has duplicate 0007752closedgiallu User groups 
has duplicate 0011003closeddhx User groups for easy managing 
has duplicate 0011867closedatrol User Groups / Custom User Fields 
has duplicate 0007614closeddregad Better user accounts administration should be implemented (to support the administration of large group of users). 
related to 0002342closedgrangeway Create groups and locations for users to belong to 
related to 0012390new Feature request: User inheritance, similar to current category inheritance 
child of 0005381new more flexible group/role/profile/permission management 
+ Relationships

-  Notes
User avatar

~0005532

lauploix (reporter)

I agree. We have 15+ projects, and mainly 5+ user groups (sales, programmers, consulting, ...).

It would be so nice to be able to manage the rights at group level... and just add a user to a group when a new user arrives.
User avatar

~0005574

dwoods (reporter)

I have implented something similar in some customizations a while ago. We have a number of distibutors of our product, and it's not always desirable for them to see ongoing issues with other distibutors (at least in management's eyes).

Basically, each bug has "group view list" associated with it. Only users in those groups can see the bug (it gets filtered out of the view_all pages as well). There is a new [Manage Groups] link to a new page in the Manage screen.

I made these changes based on 0.18.0a4, and am just in the process of porting my changes to 0.18.3. I could post it here when I'm finished if anyone's interested.
User avatar

~0005580

lauploix (reporter)

Hi dwoods, I think this is also interesting to have a 'per bug' right management sometimes. In fact, I sometimes want to enable a specific user to view/update/... a bug that he has no right on.

Pb is I usually have sg like 150+ open issues, in 15+ different projects, with 100+ users in 5+ user groups. Mantis is really great for that. But that means that I cannot manage all rights on a per bug basic.

What would be so _great_ would be : once I have a new user, I just put him in several "groups" and he gets all the update/view/manage/... rights that the groups have.

But this is no contradiction with a more specific 'per user' or 'per bug' user rights management for specific purposes.
User avatar

~0005583

nuclearspike (reporter)

in a somewhat related note, also have the auto-assignment of new issues be able to go to a user group/role. A customer enters a new problem, it first should get assigned to the triage group who verifies the bug before it gets assigned to the developer who works on that category. If it first goes to one person, that person is sometimes gone for weeks on the road and other people need to handle the triage. Our current solution is sort of hackish. We create a "Triage" user, have things assigned to them, then the triage group just checks for things assigned to that user, rather than to themselves. this, however, means that all new bugs go there and we cannot use the category auto-assignments for the actual developer. Auto-assignments may be best on a per-status level. New -> Triage, Confirmed -> Manager of the project or may go directly to the developer of that category. That's getting more into workflows... which is a separate request entirely. :D
User avatar

~0005594

dwoods (reporter)

Last edited: 2004-05-26 14:32

I've attached a diff from 0.18.3, as well as all new files in a .zip (diff includes new files) and an sql file to create new tables.

As it is right now, it doesn't actually filter out the issues in the view_all_page according to the group 'view list'. I wanted to change how i was doing this before I add it in.
Basically it went something like:

for each bug passed though all other filters
   get the group_view_list for that bug
   for each group
      if current_user is in group
         show bug
if current_user is reporter
   show bug


Also, the only way to add/remove groups to an issue is in the bug_view_advanced_page, which is clearly the wrong place. It should be in the bug_advanced_update_page.
Also I would like to add the ability to add a group to multiple bugs at the same time (via the checkboxes).

Also each user should have a 'default' group, that get added to the view list automatically when they submit new issue.

Still working on it.. :)

edited on: 05-26-04 14:32
User avatar

~0007363

nuclearspike (reporter)

this is nice, but it adds groups to be able to see individual bugs, is there a way an entire group can be associated with a project?
User avatar

~0007448

dwoods (reporter)

I have updated the patch since my posting, but forgot to update the post.
It's now diff'd from the latest from HEAD as of about a 2 months ago.

My company also wanted me to make additional modifications to allow 'projects' in addition to 'issues' (where are project is actually just another issue, only originating from within the company for one of our developers to handle). And the projects as they are now I have changed to 'products'.

Anyway, the patch I'm including has these changes in there as well. I apologize for this, but hope this at least some of the code I have written may be of some use. The user group stuff is fairly self-contained.


The user groups are only used right now for implementing an 'access-list' on a per-issue basis, as mentioned in a previous note, but it would also be nice if an issue could be assigned to a group of users. I think the basic framework is there...

I also attempted to add to the upgrade scripts to create the new tables. They seemed to work for me okay.
User avatar

~0021906

djcarr (reporter)

Last edited: 2009-05-24 23:35

View 2 revisions

With 100+ projects and 100+ users this is an area where the administration workload starts to become difficult. Being able to assign roles (or "user groups") to projects and then giving users one or several roles, would really bring Mantis into the realm of corporate applications.

Could others desiring this feature please also put a little encouragement in.. thank you :)

User avatar

~0021931

tk (reporter)

Just for comment:

As a partial workaround, I implemented "assignment groups" by creating fake users which have a mailing list as email destination. The mailing list contains all people in that group.
In that way I can assign issues to groups of people. Now since the group members are all of level developer (otherwise assignment of an issue to them would make no sense) the actual user-in-charge can assign the issue to himself as soon as he starts working on it.
User avatar

~0022027

djcarr (reporter)

Last edited: 2009-06-01 19:15

View 3 revisions

Thanks for the input 'tk' - perhaps the scenario you are talking about is covered by 0000955 or 0006644? While I can see how that may be useful it is still somewhat different to this issue which is for a users-roles-privileges engine.

User avatar

~0023105

sveyret (reporter)

Hi, I have made specifications about what I think could solve all the problems (see attached PDF file). Can you tell me your opinion about it? I hope I will find time to work on that issue soon.

Thank you.
User avatar

~0023199

sveyret (reporter)

Specifications are now added to the Wiki page so everyone can work on it…
User avatar

~0027115

andy778 (reporter)

Any idea when this will be developed and how much sponsoring would this require to get this done?
User avatar

~0028016

tiliarou (reporter)

I'm very interested by this feature ! Adding group management to Mantis would make it so much better !
Is someone still working on this issue ? Does he need more sponsoring ?
User avatar

~0028022

djcarr (reporter)

Last edited: 2011-01-20 17:58

View 3 revisions

The specs in the wiki are very detailed but represent a very large amount of work. I am not sure why the login authentication code needs to be modified.

A simpler approach to address the original request:

- New table 'mantis_role_table' with fields: role_id, name, access_level
- New table 'mantis_project_role_table' with fields: project_id, role_id, access_level
- New table 'mantis_user_role_table' with fields: user_id, role_id
- Change all access level lookups in code to include these tables as well
- Use the highest access level found for that user and project

This is a relatively straightforward change that will provide big benefits to administrators and doesn't require migration of existing data to a new structure.

User avatar

~0028101

sveyret (reporter)

I stopped working on this feature after a very big code loss at a time I was still trying to make git working… :-(
I will have no time to restart this job for the moment.
There are Mantis developpers currently working to re-write Mantis using the Zend framework. As Zend framework has got an easy way to manage access controls, this will probably be a good occasion to include group management.
User avatar

~0029464

andy778 (reporter)

What is the current plan with this?
User avatar

~0029467

cas (reporter)

Perhaps it will show up in a later version but so far there is little feedback on this. There are a few smaller patches around to group users and/or assiging sub tasks within one issue. if thos are usable for you, very much depends on your requirements
User avatar

~0029470

andy778 (reporter)

We have over 300 mantis users and over 100 projects and the projects are private so what we would like is to add users to groups alias and groups should then be added under each project. Also ldap/AD authentication is needed. Sponsoring is also possible to arrange if needed.
User avatar

~0032842

cas (reporter)

Now creating a plugin that will allow users to be connected to multiple groups (which can be defined seperately).
My tasks plugin will allow to assign tasks to one of those groups. Each task can then be handled by anyone from that group. System will register which user in the end will complete the task.
Although not full group management, it will be enough for our purposes.
User avatar

~0032872

cas (reporter)

For those interested, the plugin is available and released together with an updated version of the Tasks plugin.
See:
http://www.mantisbt.org/bugs/view.php?id=14716 [^]
User avatar

~0039801

HeikoSL (reporter)

I have created another plugin for usergroups:
This plugin can be used to create groups of users in your mantis bugtracker. You may use nested groups and you can decide if groups can handle a bug. Notifications will be send to all group members.

The plugin creates one table that holds the groups with their members. But: To use this plugin you must edit some core functions!

See: https://github.com/langerheiko/ManageUsergroups [^]
User avatar

~0040114

hincelin (reporter)

@ HeikoSL,
Thanks for this new plungin.
Can it be used with 1.2.17 ?
Sincerely
User avatar

~0040132

HeikoSL (reporter)

I am running it on 1.2.14, but I tested it with 1.2.17. It's working.
+  Notes

- Issue History
Date Modified Username Field Change
2003-12-03 03:44 TomWalter New Issue
2004-05-18 06:57 lauploix Note Added: 0005532
2004-05-24 13:08 dwoods Note Added: 0005574
2004-05-25 01:59 lauploix Note Added: 0005580
2004-05-25 10:23 nuclearspike Note Added: 0005583
2004-05-26 14:12 dwoods File Added: diff_from_RELEASE_0_18_3_20040512.diff
2004-05-26 14:13 dwoods File Added: group_new_files.zip
2004-05-26 14:13 dwoods File Added: group_tables.sql
2004-05-26 14:31 dwoods Note Added: 0005594
2004-05-26 14:32 dwoods Note Edited: 0005594
2004-07-24 09:05 grangeway Relationship added related to 0002342
2004-09-01 13:34 nuclearspike Note Added: 0007363
2004-09-05 16:10 grangeway Assigned To => grangeway
2004-09-05 18:03 dwoods File Added: usergroups_diff_from_0_19_CVS_20040529.zip
2004-09-05 18:03 dwoods Note Added: 0007448
2005-03-23 18:05 vwegert Relationship added child of 0005381
2008-07-16 14:12 grangeway Status new => assigned
2008-08-07 04:17 giallu Relationship added has duplicate 0007752
2009-05-24 23:25 djcarr Sponsorship Added djcarr: US$ 50
2009-05-24 23:25 djcarr Sponsorship Total 0 => 50
2009-05-24 23:31 djcarr Note Added: 0021906
2009-05-24 23:35 djcarr Note Edited: 0021906 View Revisions
2009-05-27 01:35 tk Note Added: 0021931
2009-06-01 19:09 djcarr Note Added: 0022027
2009-06-01 19:11 djcarr Note Edited: 0022027 View Revisions
2009-06-01 19:15 djcarr Note Edited: 0022027 View Revisions
2009-10-06 03:02 dhx Relationship added has duplicate 0011003
2009-10-09 04:55 sveyret File Added: Creating groups in Mantis.pdf
2009-10-09 04:57 sveyret Note Added: 0023105
2009-10-15 04:59 sveyret Note Added: 0023199
2010-10-22 02:31 andy778 Note Added: 0027115
2011-01-20 08:18 tiliarou Note Added: 0028016
2011-01-20 17:53 djcarr Note Added: 0028022
2011-01-20 17:54 djcarr Note Edited: 0028022 View Revisions
2011-01-20 17:58 djcarr Note Edited: 0028022 View Revisions
2011-01-27 03:28 sveyret Note Added: 0028101
2011-08-11 11:51 andy778 Note Added: 0029464
2011-08-12 03:00 cas Note Added: 0029467
2011-08-12 11:26 andy778 Note Added: 0029470
2011-08-14 08:55 atrol Relationship added has duplicate 0011867
2011-11-28 12:11 dregad Relationship added related to 0012390
2012-02-28 11:29 dregad Relationship added has duplicate 0007614
2012-09-12 11:03 dregad Assigned To grangeway =>
2012-09-12 11:03 dregad Status assigned => confirmed
2012-09-14 02:02 cas Note Added: 0032842
2012-09-19 01:45 cas Note Added: 0032872
2012-09-20 05:49 cas Tag Attached: usergroups
2014-04-01 04:37 HeikoSL Note Added: 0039801
2014-04-17 08:42 hincelin Note Added: 0040114
2014-04-22 07:57 HeikoSL Note Added: 0040132
+ Issue History