View Issue Details

IDProjectCategoryView StatusLast Update
0014565mantisbtcustom fieldspublic2017-05-17 14:19
ReporterLapinkillerAssigned To 
PrioritynormalSeverityfeatureReproducibilityhave not tried
Status confirmedResolutionopen 
Product Version1.2.8 
Target VersionFixed in Version 
Summary0014565: New Custom field User
Description

I just have added two new type of custom field :

User List and User multiselection list

Tagscustom fields

Relationships

related to 0004640 new New custom field types: "Version", "User" 
related to 0003790 acknowledged Additional Custom-Field-Type "users" 

Activities

Lapinkiller

Lapinkiller

2012-08-08 04:10

reporter   ~0032497

Last edited: 2012-08-08 04:37

View 2 revisions

patch is not fully (filters or not working), it missed some things... i will submit next patch after corrected some things ;)

rombert

rombert

2012-08-08 04:12

reporter   ~0032498

Looks interesting, looking forward to it!

Lapinkiller

Lapinkiller

2012-08-08 05:06

reporter  

customfield_userlist_patch-2.diff (12,564 bytes)
Index: lang/strings_english.txt
===================================================================
--- lang/strings_english.txt	(revision 315)
+++ lang/strings_english.txt	(revision 317)
@@ -1300,7 +1300,7 @@
 $s_linked_projects = 'Linked Projects';
 
 $s_custom_field_sequence = 'Sequence';
-$s_custom_field_type_enum_string = '0:String,1:Numeric,2:Float,3:Enumeration,4:E-mail,5:Checkbox,6:List,7:Multiselection list,8:Date,9:Radio';
+$s_custom_field_type_enum_string = '0:String,1:Numeric,2:Float,3:Enumeration,4:E-mail,5:Checkbox,6:List,7:Multiselection list,8:Date,9:Radio,10:User,11:Users multiselection list';
 
 $s_confirm_used_custom_field_deletion = 'This field is currently linked to at least one project. If you continue all values for this field will be permanently deleted. This action cannot be undone. If you do not want to delete this field, hit the Back button in your browser. To proceed, click the button below';
 $s_confirm_custom_field_deletion = 'Are you sure you want to delete this custom field and all associated values?';
Index: lang/strings_french.txt
===================================================================
--- lang/strings_french.txt	(revision 315)
+++ lang/strings_french.txt	(revision 317)
@@ -1088,7 +1088,7 @@
 $s_link_custom_field_to_project_button = 'Lier champ personnalisé';
 $s_linked_projects = 'Projets liés';
 $s_custom_field_sequence = 'Suite';
-$s_custom_field_type_enum_string = '0:Chaîne de caractères,1:Nombre entier,2:Nombre réel,3:Énumération,4:Courriel,5:Case à cocher,6:Liste,7:Liste à sélection multiple,8:Date,9:Bouton radio';
+$s_custom_field_type_enum_string = '0:Chaîne de caractères,1:Nombre entier,2:Nombre réel,3:Énumération,4:Courriel,5:Case à cocher,6:Liste,7:Liste à sélection multiple,8:Date,9:Bouton radio,10:Utilisateur,11:Liste d'utilisateurs';
 $s_confirm_used_custom_field_deletion = 'Ce champ est actuellement lié à au moins un projet.  Si vous continuez, toutes les valeurs de ce champ seront supprimées.  Cette action ne peut être annulée.  Si vous ne voulez pas supprimer ce champ, cliquer sur le bouton Retour de votre navigateur.  Sinon pour supprimer ce champ, cliquer sur le bouton ci dessous';
 $s_confirm_custom_field_deletion = 'Êtes vous sûr de vouloir supprimer ce champ personnalisé et toutes les valeurs associées ?';
 $s_field_delete_button = 'Supprimer le champ';
Index: config_defaults_inc.php
===================================================================
--- config_defaults_inc.php	(revision 315)
+++ config_defaults_inc.php	(revision 317)
@@ -3008,7 +3008,7 @@
 	 *
 	 * @global string $g_custom_field_type_enum_string
 	 */
-	$g_custom_field_type_enum_string    = '0:string,1:numeric,2:float,3:enum,4:email,5:checkbox,6:list,7:multiselection list,8:date,9:radio';
+	$g_custom_field_type_enum_string    = '0:string,1:numeric,2:float,3:enum,4:email,5:checkbox,6:list,7:multiselection list,8:date,9:radio,10:userlist,11:usermultilist';
 
 	/*********************************
 	 * MantisBT Javascript Variables *
Index: core/filter_api.php
===================================================================
--- core/filter_api.php	(revision 315)
+++ core/filter_api.php	(revision 317)
@@ -2988,7 +2988,22 @@
 									$t_values .= $t_start;
 									break;
 							}
-						} else {
+						} elseif( $t_accessible_custom_fields_types[$i] == CUSTOM_FIELD_TYPE_USER_LIST || $t_accessible_custom_fields_types[$i] == CUSTOM_FIELD_TYPE_USER_MULTILIST) {
+							$t_current = $t_filter['custom_fields'][$t_accessible_custom_fields_ids[$i]][0];
+							
+							$t_values .= '<input type="hidden" name="custom_field_' . $t_accessible_custom_fields_ids[$i] . '[]" value="' . $t_current . '" />';
+							
+							if( filter_field_is_any( $t_current ) ) {
+								$t_any_found = true;
+							} else if( filter_field_is_none( $t_current ) ) {
+								$t_this_string = lang_get( 'none' );
+							} else {
+								$t_this_string = user_get_name( $t_current);
+							}
+							
+							$t_output .= $t_this_string;
+							
+						}else{
 							$t_first_flag = true;
 							foreach( $t_filter['custom_fields'][$t_accessible_custom_fields_ids[$i]] as $t_current ) {
 								$t_current = stripslashes( $t_current );
@@ -4002,6 +4017,8 @@
 	} else if( isset( $t_accessible_custom_fields_names[$j] ) ) {
 		if( $t_accessible_custom_fields_types[$j] == CUSTOM_FIELD_TYPE_DATE ) {
 			print_filter_custom_field_date( $j, $p_field_id );
+		} elseif( $t_accessible_custom_fields_types[$j] == CUSTOM_FIELD_TYPE_USER_LIST || $t_accessible_custom_fields_types[$j] == CUSTOM_FIELD_TYPE_USER_MULTILIST ) {
+			print_filter_custom_field_user( $j, $p_field_id );
 		} else {
 			echo '<select ' . $t_select_modifier . ' name="custom_field_' . $p_field_id . '[]">';
 			echo '<option value="' . META_FILTER_ANY . '" ';
@@ -4221,6 +4238,22 @@
 	print "</td></tr>\n</table>";
 }
 
+
+function print_filter_custom_field_user( $p_field_num, $p_field_id ) {
+	global $t_filter, $t_accessible_custom_fields_names, $t_accessible_custom_fields_types, $t_accessible_custom_fields_values, $t_accessible_custom_fields_ids, $t_select_modifier;
+
+		echo '<select name="custom_field_'.$p_field_id.'[]">';
+		 	echo '<option value="' . META_FILTER_ANY . '"';
+			check_selected( $t_filter['custom_fields'][$p_field_id][0], META_FILTER_ANY );
+			echo '>' . lang_get( 'any' ) . '</option>' . "\n";
+			echo '<option value="' . META_FILTER_NONE . '"';
+			check_selected( $t_filter['custom_fields'][$p_field_id][0], META_FILTER_NONE );
+			echo '>' . lang_get( 'none' ) . '</option>' . "\n";
+			
+			print_user_option_list($t_filter['custom_fields'][$p_field_id][0],helper_get_current_project());
+		echo '</select>';
+}
+
 /**
  *  print project field
  */
Index: core/gpc_api.php
===================================================================
--- core/gpc_api.php	(revision 315)
+++ core/gpc_api.php	(revision 317)
@@ -226,6 +226,7 @@
 function gpc_get_custom_field( $p_var_name, $p_custom_field_type, $p_default = null ) {
 	switch( $p_custom_field_type ) {
 		case CUSTOM_FIELD_TYPE_MULTILIST:
+		case CUSTOM_FIELD_TYPE_USER_MULTILIST:
 		case CUSTOM_FIELD_TYPE_CHECKBOX:
 		    // ensure that the default is an array, if set
 		    if ( ($p_default !== null) && !is_array($p_default) ) {
Index: core/cfdefs/cfdef_standard.php
===================================================================
--- core/cfdefs/cfdef_standard.php	(revision 315)
+++ core/cfdefs/cfdef_standard.php	(revision 317)
@@ -158,6 +158,34 @@
 	'#function_string_value_for_email' => 'cfdef_prepare_date_value_for_email',
 );
 
+$g_custom_field_type_definition[ CUSTOM_FIELD_TYPE_USER_LIST ] = array (
+	'#display_possible_values' => FALSE,
+	'#display_valid_regexp' => FALSE,
+	'#display_length_min' => FALSE,
+	'#display_length_max' => FALSE,
+	'#display_default_value' => FALSE,
+	'#function_return_distinct_values' => 'cfdef_prepare_user_list_distinct_values',
+	'#function_value_to_database' => null,
+	'#function_database_to_value' => null,
+	'#function_print_input' => 'cfdef_input_userlist',
+	'#function_string_value' => 'cfdef_prepare_user_list_value',
+	'#function_string_value_for_email' => 'cfdef_prepare_user_database_to_value',
+);
+
+$g_custom_field_type_definition[ CUSTOM_FIELD_TYPE_USER_MULTILIST ] = array (
+	'#display_possible_values' => TRUE,
+	'#display_valid_regexp' => FALSE,
+	'#display_length_min' => FALSE,
+	'#display_length_max' => FALSE,
+	'#display_default_value' => FALSE,
+	'#function_return_distinct_values' => 'cfdef_prepare_user_list_distinct_values',
+	'#function_value_to_database' => 'cfdef_prepare_list_value_to_database',
+	'#function_database_to_value' => null,
+	'#function_print_input' => 'cfdef_input_userlist',
+	'#function_string_value' => 'cfdef_prepare_user_multilist_value',
+	'#function_string_value_for_email' => 'cfdef_prepare_user_multilist_value',
+);
+
 function cfdef_prepare_list_database_to_value($p_value) {
 	return rtrim( ltrim( $p_value, '|' ), '|' );
 }
@@ -256,6 +284,35 @@
 	echo '</select>';
 }
 
+function cfdef_input_userlist($p_field_def, $t_custom_field_value) {	
+	
+	if ( $p_field_def['type'] == CUSTOM_FIELD_TYPE_USER_MULTILIST ) {
+		$t_selected_values = explode( '|', $t_custom_field_value );
+		
+		echo '<select ', helper_get_tab_index(), ' name="custom_field_' . $p_field_def['id'] . '[]" size="' . $t_list_size . '" multiple="multiple">';
+		$t_selected_values = explode( '|', $t_custom_field_value );
+		$t_values = project_get_all_user_rows(helper_get_current_project());
+		$t_list_size = 5;
+		
+		foreach( $t_values as $t_option ) {
+			if( in_array( $t_option['id'], $t_selected_values ) ) {				
+				echo '<option value="' . $t_option['id']  . '" selected="selected">' . user_get_name( $t_option['id'] ) . '</option>';
+			} else {
+				echo '<option value="' .  $t_option['id'] . '">' . user_get_name( $t_option['id'] ) . '</option>';
+			}
+		}
+	} else {
+		echo '<select ', helper_get_tab_index(), ' name="custom_field_' . $p_field_def['id'] . '">';
+		print_user_option_list($t_custom_field_value);
+	}
+		
+	
+	
+	
+	echo '</select>';
+	
+}
+
 function cfdef_input_checkbox($p_field_def, $t_custom_field_value) {
 	$t_values = explode( '|', custom_field_prepare_possible_values( $p_field_def['possible_values'] ) );
 	$t_checked_values = explode( '|', $t_custom_field_value );
@@ -342,3 +399,29 @@
 	}
 	return $t_return_arr;
 }
+
+
+function cfdef_prepare_user_list_value($p_value){
+	return user_get_name($p_value);
+}
+
+
+function cfdef_prepare_user_multilist_value($p_value){
+	$t_userlist = explode('|',$p_value);
+	$t_return = array();
+	foreach($t_userlist as $t_user){
+		if(user_exists($t_user)){
+			$t_return[] = user_get_name($t_user);
+		}
+	}
+	return implode(', ',$t_return);
+}
+
+function cfdef_prepare_user_list_distinct_values($p_field_def){
+	$t_values = project_get_all_user_rows(helper_get_current_project());
+	$t_return = array();
+	foreach( $t_values as $t_option ) {
+		$t_return[$t_option['id']] = user_get_name($t_option['id']);
+	}
+	return $t_return;
+}
Index: core/custom_field_api.php
===================================================================
--- core/custom_field_api.php	(revision 315)
+++ core/custom_field_api.php	(revision 317)
@@ -44,15 +44,17 @@
 #	- add functions to return individual db columns for a field definition
 # *******************************************
 
-$g_custom_field_types[CUSTOM_FIELD_TYPE_STRING] = 'standard';
-$g_custom_field_types[CUSTOM_FIELD_TYPE_NUMERIC] = 'standard';
-$g_custom_field_types[CUSTOM_FIELD_TYPE_FLOAT] = 'standard';
-$g_custom_field_types[CUSTOM_FIELD_TYPE_ENUM] = 'standard';
-$g_custom_field_types[CUSTOM_FIELD_TYPE_EMAIL] = 'standard';
-$g_custom_field_types[CUSTOM_FIELD_TYPE_CHECKBOX] = 'standard';
-$g_custom_field_types[CUSTOM_FIELD_TYPE_LIST] = 'standard';
-$g_custom_field_types[CUSTOM_FIELD_TYPE_MULTILIST] = 'standard';
-$g_custom_field_types[CUSTOM_FIELD_TYPE_DATE] = 'standard';
+$g_custom_field_types[CUSTOM_FIELD_TYPE_STRING] 	= 'standard';
+$g_custom_field_types[CUSTOM_FIELD_TYPE_NUMERIC] 	= 'standard';
+$g_custom_field_types[CUSTOM_FIELD_TYPE_FLOAT] 		= 'standard';
+$g_custom_field_types[CUSTOM_FIELD_TYPE_ENUM] 		= 'standard';
+$g_custom_field_types[CUSTOM_FIELD_TYPE_EMAIL] 		= 'standard';
+$g_custom_field_types[CUSTOM_FIELD_TYPE_CHECKBOX] 	= 'standard';
+$g_custom_field_types[CUSTOM_FIELD_TYPE_LIST] 		= 'standard';
+$g_custom_field_types[CUSTOM_FIELD_TYPE_MULTILIST] 	= 'standard';
+$g_custom_field_types[CUSTOM_FIELD_TYPE_DATE] 		= 'standard';
+$g_custom_field_types[CUSTOM_FIELD_TYPE_USER_LIST]	= 'standard';
+$g_custom_field_types[CUSTOM_FIELD_TYPE_USER_MULTILIST]	= 'standard';
 
 foreach( $g_custom_field_types as $type ) {
 	require_once( 'cfdefs' . DIRECTORY_SEPARATOR . 'cfdef_' . $type . '.php' );
@@ -1226,6 +1228,11 @@
 				$t_valid &= email_is_valid( $p_value );
 			}
 			break;
+		case CUSTOM_FIELD_TYPE_USER:
+			if ( $p_value !== '' ) {
+				$t_valid &= email_is_valid( $p_value );
+			}
+			break;
 		default:
 			break;
 	}
Index: core/constant_inc.php
===================================================================
--- core/constant_inc.php	(revision 315)
+++ core/constant_inc.php	(revision 317)
@@ -421,6 +421,8 @@
 define( 'CUSTOM_FIELD_TYPE_MULTILIST', 7 );
 define( 'CUSTOM_FIELD_TYPE_DATE', 8 );
 define( 'CUSTOM_FIELD_TYPE_RADIO', 9 );
+define( 'CUSTOM_FIELD_TYPE_USER_LIST', 10 );
+define( 'CUSTOM_FIELD_TYPE_USER_MULTILIST', 11 );
 
 # Meta filter values
 define( 'META_FILTER_MYSELF', -1 );
Lapinkiller

Lapinkiller

2012-08-08 05:06

reporter   ~0032500

i hope all is working with customfield_userlist_patch-2.diff :)

atrol

atrol

2012-08-09 15:07

developer   ~0032528

Probably a good idea to get this feature.

Lapinkiller's approach to introduce a new custom field type for it might lead to have also own types for other fields in future.

After introducing CUSTOM_FIELD_TYPE_USER_LIST and CUSTOM_FIELD_TYPE_USER_MULTILIST we will get
CUSTOM_FIELD_TYPE_PROJECT_LIST
CUSTOM_FIELD_TYPE_PROJECT_MULTILIST
CUSTOM_FIELD_TYPE_VERSION_LIST
CUSTOM_FIELD_TYPE_VERSION_MULTILIST
CUSTOM_FIELD_TYPE_CATEGORY_LIST
CUSTOM_FIELD_TYPE_CATEGORY_MULTILIST
....

CUSTOM_FIELD_TYPE_USER_LIST is nothing more than a special kind of the existing enumeration type.
CUSTOM_FIELD_TYPE_USER_MULTILIST is nothing more than a special kind of the existing multiselection list type.

What about the following approach?
Extend the existing functionality of enumerations and multiselection lists to have dynamic lists.
http://www.mantisbt.org/docs/master-1.2.x/en/administration_guide.html#ADMIN.CUSTOMIZE.CUSTOMFIELDS.DYNAMIC
Introduce "=users" as a new possible value to get a user list.

Furthermore this approach allows overriding the creation of the list by a custom function.
For example reduce the user list by a custom rule (never list administrators, always add user <xyz>, ...)

rombert

rombert

2012-08-09 15:34

reporter   ~0032529

@Lapinkiller, what are your thoughts about atrol's comments? This approach is probably more flexible.

Lapinkiller

Lapinkiller

2012-08-10 02:51

reporter   ~0032533

i'm agree with Atrol about others fields.

How "Dynamic possible values" works ? i juste have tried to create new custom field of type enum with possible value : "=categories" but i only get an empty list with 4 blanks items, <option> values are empty too (i have 4 categories on the project).

"never list administrators" i have made changes in code too hide administrators (i have 2 account on mantis, an admin account and an user account).

(please delete my first patch " customfield_userlist_patch.diff")

atrol

atrol

2012-08-10 03:25

developer   ~0032534

In reply to 0014565:0032533

i juste have tried to create new custom field of type enum with possible value : "=categories"
There is probably a bug

Try =versions to see how it works.

Lapinkiller

Lapinkiller

2012-08-10 05:17

reporter   ~0032536

with version it's works

there is a problem with users,

function custom_function_overrideenum<field>() return list of values,

but in the case of user, we have to return value (id of the user in bdd) AND label (name of the user) because we can have people with same name (we use an Active Directory)

atrol

atrol

2012-08-12 06:31

developer   ~0032541

I fixed the bug with categories, see 0014587

atrol

atrol

2012-08-12 07:02

developer   ~0032542

In reply to 0014565:0032536

but in the case of user, we have to return value (id of the user in bdd) AND label (name of the user) because we can have people with same name (we use an Active Directory)

Is this a special problem of custom fields for user lists?
I don't think so.
It's the same when selecting/filtering reporters or assigned users.

rombert

rombert

2012-08-12 07:33

reporter   ~0032543

(In reply to comment 0014565:0032536)

but in the case of user, we have to return value (id of the user in bdd)

What does bdd mean?

dregad

dregad

2012-08-12 10:19

developer   ~0032544

I'd guess, French acronym for database (Base De Données)

Lapinkiller

Lapinkiller

2012-08-12 11:39

reporter   ~0032545

yes, sorry, bdd in french = db in english...

atrol

atrol

2012-08-25 13:03

developer   ~0032646

Seems that none of us noticed that this is a quite old feature request where different approaches / patches are available. See 0004640 and 0003790

Issue History

Date Modified Username Field Change
2012-08-08 04:03 Lapinkiller New Issue
2012-08-08 04:03 Lapinkiller File Added: customfield_userlist_patch.diff
2012-08-08 04:10 Lapinkiller Note Added: 0032497
2012-08-08 04:12 rombert Note Added: 0032498
2012-08-08 04:37 Lapinkiller Note Edited: 0032497 View Revisions
2012-08-08 05:06 Lapinkiller File Added: customfield_userlist_patch-2.diff
2012-08-08 05:06 Lapinkiller Note Added: 0032500
2012-08-09 15:07 atrol Note Added: 0032528
2012-08-09 15:07 atrol Severity minor => feature
2012-08-09 15:34 rombert Note Added: 0032529
2012-08-09 15:34 rombert Status new => confirmed
2012-08-09 15:34 rombert Description Updated View Revisions
2012-08-10 02:51 Lapinkiller Note Added: 0032533
2012-08-10 03:23 atrol File Deleted: customfield_userlist_patch.diff
2012-08-10 03:25 atrol Note Added: 0032534
2012-08-10 05:17 Lapinkiller Note Added: 0032536
2012-08-12 06:31 atrol Note Added: 0032541
2012-08-12 07:02 atrol Note Added: 0032542
2012-08-12 07:33 rombert Note Added: 0032543
2012-08-12 10:19 dregad Note Added: 0032544
2012-08-12 11:39 Lapinkiller Note Added: 0032545
2012-08-25 13:03 atrol Note Added: 0032646
2012-08-25 13:03 atrol Relationship added related to 0004640
2012-08-25 13:03 atrol Relationship added related to 0003790
2013-06-06 10:57 Lapinkiller Tag Attached: custom fields