View Issue Details

IDProjectCategoryView StatusLast Update
0009946mantisbtcode cleanuppublic2009-01-15 11:26
Reportervboctor Assigned Tovboctor  
PrioritynormalSeverityminorReproducibilityhave not tried
Status closedResolutionfixed 
Product Version1.2.0a2 
Fixed in Version1.2.0a3 
Summary0009946: Refactor enumeration handling and add unit tests for it
Description

The main aim of this is to introduce the concept of automated unit testing in MantisBT via the use of PHPUnit. This work will involve the following:

  1. Replace misc. methods related to enumeration with MantisEnum class.
  2. Add unit tests for MantisEnum class built using the PHPUnit framework.
  3. Update the code to use MantisEnum rather than the misc. methods.
Tagspatch
Attached Files
enums_ut_01.patch (60,129 bytes)   
diff --git a/adm_permissions_report.php b/adm_permissions_report.php
index ed9efd3..4fdbd6e 100644
--- a/adm_permissions_report.php
+++ b/adm_permissions_report.php
@@ -37,27 +37,27 @@
 	print_manage_config_menu( 'adm_permissions_report.php' );
 
 	function get_section_begin( $p_section_name ) {
-		$t_access_levels = explode_enum_string( config_get( 'access_levels_enum_string' ) );
+		$t_access_levels = MantisEnum::getValues( config_get( 'access_levels_enum_string' ) );
+
 		$t_output = '<table class="width100">';
 		$t_output .= '<tr><td class="form-title" colspan="' . ( count( $t_access_levels ) + 1 ) . '">' . strtoupper( $p_section_name ) . '</td></tr>' . "\n";
 		$t_output .= '<tr><td class="form-title" width="40%">' . lang_get( 'perm_rpt_capability' ) . '</td>';
+
 		foreach( $t_access_levels as $t_access_level ) {
-			$t_entry_array = explode_enum_arr( $t_access_level );
-			$t_output .= '<td class="form-title" style="text-align:center">&nbsp;' . get_enum_to_string( lang_get( 'access_levels_enum_string' ), $t_entry_array[0] ) . '&nbsp;</td>';
+			$t_output .= '<td class="form-title" style="text-align:center">&nbsp;' . MantisEnum::getLabel( lang_get( 'access_levels_enum_string' ), $t_access_level ) . '&nbsp;</td>';
 		}
+
 		$t_output .= '</tr>' . "\n";
 
 		return $t_output;
 	}
 
 	function get_capability_row( $p_caption, $p_access_level ) {
-		$t_access_levels = explode_enum_string( config_get( 'access_levels_enum_string' ) );
+		$t_access_levels = MantisEnum::getValues( config_get( 'access_levels_enum_string' ) );
 
 		$t_output = '<tr ' . helper_alternate_class() . '><td>' . string_display( $p_caption ) . '</td>';
 		foreach( $t_access_levels as $t_access_level ) {
-			$t_entry_array = explode_enum_arr( $t_access_level );
-
-			if ( (int)$t_entry_array[0] >= (int)$p_access_level ) {
+			if ( $t_access_level >= (int)$p_access_level ) {
 				$t_value = '<img src="images/ok.gif" width="20" height="15" alt="X" title="X" />';
 			} else {
 				$t_value = '&nbsp;';
diff --git a/api/soap/mc_api.php b/api/soap/mc_api.php
index 80d4fd4..a6a98fc 100644
--- a/api/soap/mc_api.php
+++ b/api/soap/mc_api.php
@@ -189,21 +189,10 @@ function mci_get_mantis_path() {
 
 # Given a enum string and num, return the appropriate localized string
 function mci_get_enum_element( $p_enum_name, $p_val, $p_lang ) {
-	$config_var = config_get( $p_enum_name . '_enum_string' );
-	$string_var = lang_get( $p_enum_name . '_enum_string', $p_lang );
-
-	# use the global enum string to search
-	$t_arr = explode_enum_string( $config_var );
-	$t_arr_count = count( $t_arr );
-	for( $i = 0;$i < $t_arr_count;$i++ ) {
-		$elem_arr = explode_enum_arr( $t_arr[$i] );
-		if( $elem_arr[0] == $p_val ) {
-
-			# now get the appropriate translation
-			return get_enum_to_string( $string_var, $p_val );
-		}
-	}
-	return '@' . $p_val . '@';
+	$t_enum_string = config_get( $p_enum_name . '_enum_string' );
+	$t_localized_enum_string = lang_get( $p_enum_name . '_enum_string', $p_lang );
+
+	return MantisEnum::getLocalizedLabel( $t_enum_string, $t_localized_enum_string, $p_val );
 }
 
 # Gets the sub-projects that are accessible to the specified user / project.
diff --git a/api/soap/mc_enum_api.php b/api/soap/mc_enum_api.php
index 0df3f03..bff6f74 100644
--- a/api/soap/mc_enum_api.php
+++ b/api/soap/mc_enum_api.php
@@ -169,13 +169,18 @@ function mci_explode_to_objectref( $p_config_enum_string ) {
 	if( get_class( $p_config_enum_string ) == 'soap_fault' ) {
 		return $p_config_enum_string;
 	}
-	foreach( explode_enum_string( $p_config_enum_string ) as $t_enum_element ) {
-		list( $t_id, $t_name ) = explode_enum_arr( $t_enum_element );
+	
+	$t_result = array();
+
+	$t_assoc_array = MantisEnum::getAssocArrayIndexedByValues( $p_config_enum_string );
+
+	foreach ( $t_assoc_array as $t_id => $t_name ) {
 		$t_result[] = array(
 			'id' => $t_id,
 			'name' => $t_name,
 		);
-	};
+	}
+
 	return $t_result;
 }
 
@@ -203,17 +208,12 @@ function mci_enum_get_array_by_id( $p_enum_id, $p_enum_type, $p_lang ) {
  * @return The id corresponding to the given label, or 0 if not found.
  */
 function mci_get_enum_value_from_label( $p_enum_string, $p_label ) {
-	$t_arr = explode_enum_string( $p_enum_string );
-	$enum_count = count( $t_arr );
-
-	for( $i = 0;$i < $enum_count;$i++ ) {
-		$t_s = explode_enum_arr( $t_arr[$i] );
-		if( $t_s[1] == $p_label ) {
-			return $t_s[0];
-		}
+	$t_value = MantisEnum::getValue( $p_enum_string, $p_label );
+	if ( $t_value === false ) {
+		return 0;
 	}
-
-	return 0;
+	
+	return $t_value;
 }
 
 /**
diff --git a/bug_change_status_page.php b/bug_change_status_page.php
index 2a0dd36..86d4be7 100644
--- a/bug_change_status_page.php
+++ b/bug_change_status_page.php
@@ -80,7 +80,7 @@
 		}
 	}
 
-	$t_status_label = str_replace( " ", "_", get_enum_to_string( config_get( 'status_enum_string' ), $f_new_status ) );
+	$t_status_label = str_replace( " ", "_", MantisEnum::getLabel( config_get( 'status_enum_string' ), $f_new_status ) );
 	$t_resolved = config_get( 'bug_resolved_status_threshold' );
 
 	$t_bug = bug_get( $f_bug_id );
diff --git a/bug_graph_bystatus.php b/bug_graph_bystatus.php
index 881f130..4919faa 100644
--- a/bug_graph_bystatus.php
+++ b/bug_graph_bystatus.php
@@ -74,8 +74,8 @@
 	$t_start = $t_interval->get_start_timestamp();
 	
 	// grab all status levels
-	$t_status_arr  = get_enum_to_array( config_get( 'status_enum_string' ) );
-	$t_status_labels  = get_enum_to_array( lang_get( 'status_enum_string' ) );
+	$t_status_arr  = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) );
+	$t_status_labels  = MantisEnum::getAssocArrayIndexedByValues( lang_get( 'status_enum_string' ) );
     
     $t_bug = array();
     $t_view_status = array();
diff --git a/core.php b/core.php
index 8b08ce1..4669c89 100644
--- a/core.php
+++ b/core.php
@@ -82,8 +82,20 @@
 	$t_core_path = dirname(__FILE__).DIRECTORY_SEPARATOR.'core'.DIRECTORY_SEPARATOR;
 	if (isset($GLOBALS['g_core_path']) && !isset( $HTTP_GET_VARS['g_core_path'] ) && !isset( $HTTP_POST_VARS['g_core_path'] ) && !isset( $HTTP_COOKIE_VARS['g_core_path'] ) ) {
 		$t_core_path = $g_core_path;
-	}	
+	}
+	
+	$g_core_path = $t_core_path;
+
+	# Define an autoload function to automatically load classes when referenced.
+	function __autoload( $className ) {
+		global $g_core_path;
 
+		$t_require_path = $g_core_path . 'classes' . DIRECTORY_SEPARATOR . $className . '.class.php';
+
+		if ( file_exists( $t_require_path ) ) {
+			require_once( $t_require_path );
+		}
+	}
 
 	if ( ($t_output = ob_get_contents()) != '') {
 		echo 'Possible Whitespace/Error in Configuration File - Aborting. Output so far follows:<br />';
diff --git a/core/bug_api.php b/core/bug_api.php
index 8e28916..3b46649 100644
--- a/core/bug_api.php
+++ b/core/bug_api.php
@@ -449,30 +449,16 @@ function bug_check_workflow( $p_bug_status, $p_wanted_status ) {
 		# workflow not defined, use default enum
 		return true;
 	}
-	elseif( $p_bug_status == $p_wanted_status ) {
 
+	if ( $p_bug_status == $p_wanted_status ) {
 		# no change in state, allow the transition
 		return true;
-	} else {
-		# workflow defined - find allowed states
-		$t_allowed_states = $t_status_enum_workflow[$p_bug_status];
-		$t_arr = explode_enum_string( $t_allowed_states );
-
-		$t_enum_count = count( $t_arr );
-
-		for( $i = 0;$i < $t_enum_count;$i++ ) {
-
-			# check if wanted status is allowed
-			$t_elem = explode_enum_arr( $t_arr[$i] );
-			if( $p_wanted_status == $t_elem[0] ) {
-				return true;
-			}
-		}
-
-		# end for
 	}
 
-	return false;
+	# workflow defined - find allowed states
+	$t_allowed_states = $t_status_enum_workflow[$p_bug_status];
+
+	return MantisEnum::hasValue( $t_allowed_states, $p_wanted_status );
 }
 
 # ===================================
@@ -1137,7 +1123,7 @@ function bug_update( $p_bug_id, $p_bug_data, $p_update_extended = false, $p_bypa
 
 		# status changed
 		if( $t_old_data->status != $p_bug_data->status ) {
-			$t_status = get_enum_to_string( config_get( 'status_enum_string' ), $p_bug_data->status );
+			$t_status = MantisEnum::getLabel( config_get( 'status_enum_string' ), $p_bug_data->status );
 			$t_status = str_replace( ' ', '_', $t_status );
 			email_generic( $p_bug_id, $t_status, $t_status_prefix . $t_status );
 			return true;
diff --git a/core/classes/MantisEnum.class.php b/core/classes/MantisEnum.class.php
new file mode 100644
index 0000000..60a2953
--- /dev/null
+++ b/core/classes/MantisEnum.class.php
@@ -0,0 +1,206 @@
+<?php
+# Mantis - a php based bugtracking system
+
+# Mantis is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# Mantis is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Mantis.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * @package MantisBT
+ * @copyright Copyright (C) 2000 - 2009  Mantis Team - mantisbt-dev@lists.sourceforge.net
+ * @link http://www.mantisbt.org
+ */
+
+/**
+ * A class that handles Mantis Enumerations.
+ * 
+ * For example: 10:lablel1,20:label2
+ */
+class MantisEnum {
+	/**
+	 * Separator that is used to separate the enum values from their labels.
+	 */
+	const VALUE_LABEL_SEPARATOR = ':';
+	
+	/**
+	 * Separator that is used to separate the enum tuples within an enumeration definition.
+	 */
+	const TUPLE_SEPARATOR = ',';
+
+	/**
+	 * Get the string associated with the $p_enum value
+	 *
+	 * @param string $enumString
+	 * @param int $value
+	 * @return string
+	 */
+	public static function getLabel( $enumString, $value ) {
+		$assocArray = MantisEnum::getAssocArrayIndexedByValues( $enumString );
+		$valueAsInteger = (int)$value;
+
+		if ( isset( $assocArray[$valueAsInteger] ) ) {
+			return $assocArray[$valueAsInteger];
+		}
+
+		return MantisEnum::getLabelForUnknownValue( $valueAsInteger );
+	}
+
+	/**
+	 * Gets the localized label corresponding to a value.  Note that this method
+	 * takes in the standard / localized enums so that if the value is in the localized
+	 * enum but not the standard one, then it returns not found.
+	 * 
+	 * @param string $enumString The standard enum string.
+	 * @param string $localizedEnumString  The localized enum string.
+	 * @param integer $value  The value to lookup.
+	 * 
+	 * @return the label or the decorated value to represent not found.
+	 */	
+	public static function getLocalizedLabel( $enumString, $localizedEnumString, $value ) {
+		if ( !MantisEnum::hasValue( $enumString, $value ) ) {
+			return MantisEnum::getLabelForUnknownValue( $value );
+		}
+		
+		return MantisEnum::getLabel( $localizedEnumString, $value );
+	}
+	
+	/**
+	 * Gets the value associated with the specified label.
+	 * 
+	 * @param string $enumString  The enumerated string.
+	 * @param string $label       The label to map.
+	 * @return integer value of the enum or false if not found.
+	 */
+	public static function getValue( $enumString, $label ) {
+		$assocArrayByLabels = MantisEnum::getAssocArrayIndexedByLabels( $enumString );
+
+		if ( isset( $assocArrayByLabels[$label] ) ) {
+			return $assocArrayByLabels[$label];
+		}
+
+		return false;
+	}
+
+	/**
+	 * Get an associate array for the tuples of the enum where the values
+	 * are the array indices and the labels are the array values.
+	 *
+	 * @param string $enumString
+	 * @return associate array indexed by labels.
+	 */
+	public static function getAssocArrayIndexedByValues( $enumString ) {
+		$tuples = MantisEnum::getArrayOfTuples( $enumString );
+		$tuplesCount = count( $tuples );
+		
+		$assocArray = array();
+
+		foreach ( $tuples as $tuple ) {
+			$tupleTokens = MantisEnum::getArrayForTuple( $tuple );
+
+			# if not a proper tuple, skip.
+			if ( count( $tupleTokens ) != 2 ) {
+				continue;
+			}
+
+			$value = (int) trim( $tupleTokens[0] );
+
+			# if already set, skip.
+			if ( isset( $assocArray[ $value ] ) ) {
+				continue;
+			}
+			
+			$label = trim( $tupleTokens[1] );
+
+			$assocArray[$value] = $label;
+		}
+
+		return $assocArray;
+	}
+	
+	/**
+	 * Get an associate array for the tuples of the enum where the labels
+	 * are the array indices and the values are the array values.
+	 *
+	 * @param string $enumString
+	 * @return associate array indexed by labels.
+	 */
+	public static function getAssocArrayIndexedByLabels( $enumString ) {
+		return array_flip( MantisEnum::getAssocArrayIndexedByValues( $enumString ) );
+	}
+
+	/**
+	 * Gets an array with all values in the enum.
+	 * 
+	 * @param $enumString
+	 * @return array of unique values.
+	 */
+	public static function getValues( $enumString ) {
+		return array_unique( array_keys( MantisEnum::getAssocArrayIndexedByValues( $enumString ) ) );
+	}
+
+	/**
+	 * Checks if the specified enum string contains the specified value.
+	 * 
+	 * @param string $enumString  The enumeration string.
+	 * @param integer $value      The value to chec,
+	 * @return bool true if found, false otherwise.
+	 */	
+	public static function hasValue( $enumString, $value ) {
+		$assocArray = MantisEnum::getAssocArrayIndexedByValues( $enumString );	
+		$valueAsInteger = (int)$value;
+		return isset( $assocArray[$valueAsInteger] );
+	}
+
+	/**
+	 * Breaks up an enum string into num:value elements
+	 *
+	 * @param string $enumString enum string
+	 * @return array array of num:value elements
+	 */
+	private static function getArrayOfTuples( $enumString ) {
+		if ( strlen( trim( $enumString ) ) == 0 ) {
+			return array();			
+		}
+
+		$rawArray = explode( MantisEnum::TUPLE_SEPARATOR, $enumString );
+		$trimmedArray = array();
+
+		foreach ( $rawArray as $tuple ) {
+			$trimmedArray[] = trim( $tuple );
+		}
+
+		return $trimmedArray;
+	}
+
+	/**
+	 * Given one num:value pair it will return both in an array
+	 * num will be first (element 0) value second (element 1)
+	 *
+	 * @param string $tuple a num:value pair
+	 * @return array array(value, label)
+	 */
+	private function getArrayForTuple( $tuple ) {
+		return explode( MantisEnum::VALUE_LABEL_SEPARATOR, $tuple );
+	}
+
+	/**
+	 * Given a value it decorates it and returns it as the label.
+	 * 
+	 * @param integer The value (e.g. 50).
+	 * @return The decorated value (e.g. @50@).
+	 */
+	private static function getLabelForUnknownValue( $value ) {
+		$valueAsInteger = (int)$value;
+		return '@' . $valueAsInteger . '@';
+	}
+}
+?>
\ No newline at end of file
diff --git a/core/email_api.php b/core/email_api.php
index 4d76663..da933c2 100644
--- a/core/email_api.php
+++ b/core/email_api.php
@@ -332,7 +332,7 @@ function email_collect_recipients( $p_bug_id, $p_notify_type, $p_extra_user_ids_
 	#  get list of status values that are not covered specifically in the prefs
 	#  These are handled by email_on_status generically
 	#  @@@ thraxisp note that email_on_assigned was co-opted to handle change in handler
-	$t_status_change = get_enum_to_array( config_get( 'status_enum_string' ) );
+	$t_status_change = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) );
 	unset( $t_status_change[NEW_] );
 	unset( $t_status_change[FEEDBACK] );
 	unset( $t_status_change[RESOLVED] );
diff --git a/core/file_api.php b/core/file_api.php
index 76a16ea..dad0232 100644
--- a/core/file_api.php
+++ b/core/file_api.php
@@ -532,7 +532,7 @@ function file_type_check( $p_file_name ) {
 	$t_extension = $t_ext_array[$last_position];
 
 	# check against disallowed files
-	$t_disallowed_arr = explode_enum_string( $t_disallowed_files );
+	$t_disallowed_arr = explode( ',', $t_disallowed_files );
 	foreach( $t_disallowed_arr as $t_val ) {
 		if( 0 == strcasecmp( $t_val, $t_extension ) ) {
 			return false;
@@ -545,7 +545,7 @@ function file_type_check( $p_file_name ) {
 	}
 
 	# check against allowed files
-	$t_allowed_arr = explode_enum_string( $t_allowed_files );
+	$t_allowed_arr = explode( ',', $t_allowed_files );
 	foreach( $t_allowed_arr as $t_val ) {
 		if( 0 == strcasecmp( $t_val, $t_extension ) ) {
 			return true;
diff --git a/core/filter_api.php b/core/filter_api.php
index 8fa44ac..70c82bb 100644
--- a/core/filter_api.php
+++ b/core/filter_api.php
@@ -1256,13 +1256,8 @@ function filter_get_bug_rows( &$p_page_number, &$p_per_page, &$p_page_count, &$p
 	# show / hide status
 	# take a list of all available statuses then remove the ones that we want hidden, then make sure
 	# the ones we want shown are still available
-	$t_status_arr = explode_enum_string( config_get( 'status_enum_string' ) );
-	$t_available_statuses = array();
 	$t_desired_statuses = array();
-	foreach( $t_status_arr as $t_this_status ) {
-		$t_this_status_arr = explode_enum_arr( $t_this_status );
-		$t_available_statuses[] = $t_this_status_arr[0];
-	}
+	$t_available_statuses = MantisEnum::getValues( config_get( 'status_enum_string' ) );
 
 	if( 'simple' == $t_filter['_view_type'] ) {
 
diff --git a/core/graph_api.php b/core/graph_api.php
index fcd680d..2f38fda 100644
--- a/core/graph_api.php
+++ b/core/graph_api.php
@@ -421,21 +421,17 @@ function create_bug_enum_summary( $p_enum_string, $p_enum ) {
 	$t_user_id = auth_get_current_user_id();
 	$specific_where = " AND " . helper_project_specific_where( $t_project_id, $t_user_id );
 
-	$t_arr = explode_enum_string( $p_enum_string );
-	$enum_count = count( $t_arr );
-	for( $i = 0;$i < $enum_count;$i++ ) {
-		$t_s = explode_enum_arr( $t_arr[$i] );
-		$c_s[0] = addslashes( $t_s[0] );
-		$t_key = get_enum_to_string( $p_enum_string, $t_s[0] );
+	$t_metrics = array();
+	$t_assoc_array = MantisEnum::getAssocArrayIndexedByValues( $p_enum_string );
 
+	foreach ( $t_assoc_array as $t_value => $t_label  ) {
 		$query = "SELECT COUNT(*)
 					FROM $t_bug_table
-					WHERE $p_enum='$c_s[0]' $specific_where";
+					WHERE $p_enum='$t_value' $specific_where";
 		$result = db_query( $query );
-		$t_metrics[$t_key] = db_result( $result, 0 );
+		$t_metrics[$t_label] = db_result( $result, 0 );
 	}
 
-	# end for
 	return $t_metrics;
 }
 
@@ -450,36 +446,33 @@ function enum_bug_group( $p_enum_string, $p_enum ) {
 	$t_clo_val = CLOSED;
 	$specific_where = " AND " . helper_project_specific_where( $t_project_id, $t_user_id );
 
-	$t_arr = explode_enum_string( $p_enum_string );
-	$enum_count = count( $t_arr );
-	for( $i = 0;$i < $enum_count;$i++ ) {
-		$t_s = explode( ':', $t_arr[$i] );
-		$t_key = get_enum_to_string( $p_enum_string, $t_s[0] );
-
+	$t_array_indexed_by_enum_values = MantisEnum::getAssocArrayIndexedByValues( $p_enum_string );
+	$enum_count = count( $t_array_indexed_by_enum_values );
+	foreach ( $t_array_indexed_by_enum_values as $t_value => $t_label ) {
 		# Calculates the number of bugs opened and puts the results in a table
 		$query = "SELECT COUNT(*)
 					FROM $t_bug_table
-					WHERE $p_enum='$t_s[0]' AND
+					WHERE $p_enum='$t_value' AND
 						status<'$t_res_val' $specific_where";
 		$result2 = db_query( $query );
-		$t_metrics['open'][$t_key] = db_result( $result2, 0, 0 );
+		$t_metrics['open'][$t_label] = db_result( $result2, 0, 0 );
 
 		# Calculates the number of bugs closed and puts the results in a table
 		$query = "SELECT COUNT(*)
 					FROM $t_bug_table
-					WHERE $p_enum='$t_s[0]' AND
+					WHERE $p_enum='$t_value' AND
 						status='$t_clo_val' $specific_where";
 		$result2 = db_query( $query );
-		$t_metrics['closed'][$t_key] = db_result( $result2, 0, 0 );
+		$t_metrics['closed'][$t_label] = db_result( $result2, 0, 0 );
 
 		# Calculates the number of bugs resolved and puts the results in a table
 		$query = "SELECT COUNT(*)
 					FROM $t_bug_table
-					WHERE $p_enum='$t_s[0]' AND
+					WHERE $p_enum='$t_value' AND
 						status>='$t_res_val'  AND
 						status<'$t_clo_val' $specific_where";
 		$result2 = db_query( $query );
-		$t_metrics['resolved'][$t_key] = db_result( $result2, 0, 0 );
+		$t_metrics['resolved'][$t_label] = db_result( $result2, 0, 0 );
 	}
 
 	# ## end for
diff --git a/core/helper_api.php b/core/helper_api.php
index 5ed9c87..a3d87b1 100644
--- a/core/helper_api.php
+++ b/core/helper_api.php
@@ -60,30 +60,12 @@ function helper_alternate_class( $p_index = null, $p_odd_class = "row-1", $p_eve
 # --------------------
 # get the color string for the given status
 function get_status_color( $p_status ) {
-	$t_status_enum_string = config_get( 'status_enum_string' );
+	$t_status_label = MantisEnum::getLabel( config_get( 'status_enum_string' ), $p_status );
 	$t_status_colors = config_get( 'status_colors' );
-
-	# This code creates the appropriate variable name
-	# then references that color variable
-	# You could replace this with a bunch of if... then... else
-	# statements
-
-	$t_color_str = 'closed';
 	$t_color = '#ffffff';
-	$t_arr = explode_enum_string( $t_status_enum_string );
-	$t_arr_count = count( $t_arr );
-	for( $i = 0;$i < $t_arr_count;$i++ ) {
-		$elem_arr = explode_enum_arr( $t_arr[$i] );
-		if( $elem_arr[0] == $p_status ) {
-
-			# now get the appropriate translation
-			$t_color_str = $elem_arr[1];
-			break;
-		}
-	}
 
-	if( isset( $t_status_colors[$t_color_str] ) ) {
-		$t_color = $t_status_colors[$t_color_str];
+	if ( isset( $t_status_colors[$t_status_label] ) ) {
+		$t_color = $t_status_colors[$t_status_label];
 	}
 
 	return $t_color;
@@ -94,19 +76,8 @@ function get_status_color( $p_status ) {
 function get_enum_element( $p_enum_name, $p_val ) {
 	$config_var = config_get( $p_enum_name . '_enum_string' );
 	$string_var = lang_get( $p_enum_name . '_enum_string' );
-
-	# use the global enum string to search
-	$t_arr = explode_enum_string( $config_var );
-	$t_arr_count = count( $t_arr );
-	for( $i = 0;$i < $t_arr_count;$i++ ) {
-		$elem_arr = explode_enum_arr( $t_arr[$i] );
-		if( $elem_arr[0] == $p_val ) {
-
-			# now get the appropriate translation
-			return get_enum_to_string( $string_var, $p_val );
-		}
-	}
-	return '@' . $p_val . '@';
+	
+	return MantisEnum::getLocalizedLabel( $config_var, $string_var, $p_val );
 }
 
 # --------------------
diff --git a/core/html_api.php b/core/html_api.php
index 6ba52e6..fa35c52 100644
--- a/core/html_api.php
+++ b/core/html_api.php
@@ -980,9 +980,8 @@ function html_status_legend() {
 	PRINT '<table class="width100" cellspacing="1">';
 	PRINT '<tr>';
 
-	$t_status_array = get_enum_to_array( config_get( 'status_enum_string' ) );
-
-	$t_status_names = get_enum_to_array( lang_get( 'status_enum_string' ) );
+	$t_status_array = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) );
+	$t_status_names = MantisEnum::getAssocArrayIndexedByValues( lang_get( 'status_enum_string' ) );
 	$enum_count = count( $t_status_array );
 
 	# read through the list and eliminate unused ones for the selected project
@@ -1040,8 +1039,8 @@ function html_status_percentage_legend() {
 		$t_bug_count += $row['number'];
 	}
 
-	$t_arr = explode_enum_string( config_get( 'status_enum_string' ) );
-	$enum_count = count( $t_arr );
+	$t_enum_values = MantisEnum::getValues( config_get( 'status_enum_string' ) );
+	$enum_count = count( $t_enum_values );
 
 	if( $t_bug_count > 0 ) {
 		echo '<br />';
@@ -1051,12 +1050,10 @@ function html_status_percentage_legend() {
 		echo '</tr>';
 		echo '<tr>';
 
-		for( $i = 0;$i < $enum_count;$i++ ) {
-			$t_s = explode_enum_arr( $t_arr[$i] );
-			$t_color = get_status_color( $t_s[0] );
-			$t_status = $t_s[0];
+		foreach ( $t_enum_values as $t_status ) {
+			$t_color = get_status_color( $t_status );
 
-			if( !isset( $t_status_count_array[$t_status] ) ) {
+			if ( !isset( $t_status_count_array[$t_status] ) ) {
 				$t_status_count_array[$t_status] = 0;
 			}
 
diff --git a/core/print_api.php b/core/print_api.php
index 444d790..fd73ab4 100644
--- a/core/print_api.php
+++ b/core/print_api.php
@@ -482,24 +482,6 @@ function print_news_string_by_news_id( $p_news_id ) {
 }
 
 # --------------------
-# Used for update pages
-function print_field_option_list( $p_list, $p_item = '' ) {
-	$t_mantis_bug_table = db_get_table( 'mantis_bug_table' );
-
-	$t_category_string = get_enum_string( $t_mantis_bug_table, $p_list );
-	$t_arr = explode_enum_string( $t_category_string );
-	$entry_count = count( $t_arr );
-	for( $i = 0;$i < $entry_count;$i++ ) {
-		$t_s = str_replace( '\'', '', $t_arr[$i] );
-		PRINT "<option value=\"$t_s\"";
-		check_selected( $p_item, $t_s );
-		PRINT ">$t_s</option>";
-	}
-
-	# end for
-}
-
-# --------------------
 function print_assign_to_option_list( $p_user_id = '', $p_project_id = null, $p_threshold = null ) {
 
 	if( null === $p_threshold ) {
@@ -929,19 +911,16 @@ function print_build_option_list( $p_build = '' ) {
 function print_enum_string_option_list( $p_enum_name, $p_val = 0 ) {
 	$t_config_var_name = $p_enum_name . '_enum_string';
 	$t_config_var_value = config_get( $t_config_var_name );
+	
+	$t_enum_values = MantisEnum::getValues( $t_config_var_value );
 
-	$t_arr = explode_enum_string( $t_config_var_value );
-	$t_enum_count = count( $t_arr );
-	for( $i = 0;$i < $t_enum_count;$i++ ) {
-		$t_elem = explode_enum_arr( $t_arr[$i] );
-		$t_key = trim( $t_elem[0] );
+	foreach ( $t_enum_values as $t_key ) {
 		$t_elem2 = get_enum_element( $p_enum_name, $t_key );
+
 		echo "<option value=\"$t_key\"";
 		check_selected( $p_val, $t_key );
 		echo ">$t_elem2</option>";
 	}
-
-	# end for
 }
 
 # Select the proper enum values for status based on workflow
@@ -954,36 +933,34 @@ function get_status_option_list( $p_user_auth = 0, $p_current_value = 0, $p_show
 
 	if( count( $t_enum_workflow ) < 1 ) {
 		# workflow not defined, use default enum
-		$t_arr = explode_enum_string( $t_config_var_value );
+		$t_enum_values = MantisEnum::getValues( $t_config_var_value );
 	} else {
 		# workflow defined - find allowed states
 		if( isset( $t_enum_workflow[$p_current_value] ) ) {
-			$t_arr = explode_enum_string( $t_enum_workflow[$p_current_value] );
+			$t_enum_values = MantisEnum::getValues( $t_enum_workflow[$p_current_value] );
 		} else {
 			# workflow was not set for this status, this shouldn't happen
-			$t_arr = explode_enum_string( $t_config_var_value );
+			$t_enum_values = MantisEnum::getValues( $t_config_var_value );
 		}
 	}
 
-	$t_enum_count = count( $t_arr );
 	$t_enum_list = array();
 
-	for( $i = 0;$i < $t_enum_count;$i++ ) {
-		$t_elem = explode_enum_arr( $t_arr[$i] );
-		if( ( access_compare_level( $p_user_auth, access_get_status_threshold( $t_elem[0] ) ) ) 
-				&& ( !(( false == $p_show_current ) && ( $p_current_value == $t_elem[0] ) ) ) ) {
-			$t_enum_list[$t_elem[0]] = get_enum_element( 'status', $t_elem[0] );
+	foreach ( $t_enum_values as $t_enum_value ) {
+		if ( ( access_compare_level( $p_user_auth, access_get_status_threshold( $t_enum_value ) ) ) 
+				&& ( !(( false == $p_show_current ) && ( $p_current_value == $t_enum_value ) ) ) ) {
+			$t_enum_list[$t_enum_value] = get_enum_element( 'status', $t_enum_value );
 		}
 	}
 
-	# end for
-	if( true == $p_show_current ) {
+	if ( $p_show_current ) {
 		$t_enum_list[$p_current_value] = get_enum_element( 'status', $p_current_value );
 	}
-	if(( true == $p_add_close ) && 
-			( access_compare_level( $p_current_value, config_get( 'bug_resolved_status_threshold' ) ) ) ) {
+
+	if ( $p_add_close && access_compare_level( $p_current_value, config_get( 'bug_resolved_status_threshold' ) ) ) {
 		$t_enum_list[CLOSED] = get_enum_element( 'status', CLOSED );
 	}
+
 	return $t_enum_list;
 }
 
@@ -1006,7 +983,7 @@ function print_status_option_list( $p_select_label, $p_current_value = 0, $p_all
 		}
 		echo '</select>';
 	} else {
-		echo get_enum_to_string( 'status_enum_string', $p_current_value );
+		echo MantisEnum::getLabel( 'status_enum_string', $p_current_value );
 	}
 }
 
@@ -1028,20 +1005,19 @@ function print_project_access_levels_option_list( $p_val, $p_project_id = null )
 	PRINT "<option value=\"" . DEFAULT_ACCESS_LEVEL . "\"";
 	PRINT ">[" . lang_get( 'default_access_level' ) . "]</option>";
 
-	$t_arr = explode_enum_string( $t_access_levels_enum_string );
-	$enum_count = count( $t_arr );
-	for( $i = 0;$i < $enum_count;$i++ ) {
-		$t_elem = explode_enum_arr( $t_arr[$i] );
+	$t_enum_values = MantisEnum::getValues( $t_access_levels_enum_string );
 
+	foreach ( $t_enum_values as $t_enum_value ) {
 		# a user must not be able to assign another user an access level that is higher than theirs.
-		if( $t_elem[0] > $t_current_user_access_level ) {
+		if ( $t_enum_value > $t_current_user_access_level ) {
 			continue;
 		}
 
-		$t_access_level = get_enum_element( 'access_levels', $t_elem[0] );
-		PRINT "<option value=\"$t_elem[0]\"";
-		check_selected( $p_val, $t_elem[0] );
-		PRINT ">$t_access_level</option>";
+		$t_access_level = get_enum_element( 'access_levels', $t_enum_value );
+
+		echo "<option value=\"$t_enum_value\"";
+		check_selected( $p_val, $t_enum_value );
+		echo ">$t_access_level</option>";
 	}
 
 	# end for
diff --git a/core/summary_api.php b/core/summary_api.php
index deddcb1..e5d5d4d 100644
--- a/core/summary_api.php
+++ b/core/summary_api.php
@@ -51,8 +51,6 @@ function summary_print_by_enum( $p_enum_string, $p_enum ) {
 	}
 
 	$t_filter_prefix = config_get( 'bug_count_hyperlink_prefix' );
-	$t_arr = explode_enum_string( $p_enum_string );
-	$enum_count = count( $t_arr );
 
 	$t_mantis_bug_table = db_get_table( 'mantis_bug_table' );
 	$t_status_query = ( 'status' == $p_enum ) ? '' : ' ,status ';
@@ -764,14 +762,9 @@ function summary_print_developer_resolution( $p_resolution_enum_string ) {
 	$t_project_id = helper_get_current_project();
 	$t_user_id = auth_get_current_user_id();
 
-	# Organise an array of resolution values to be used later
-	$t_res_arr = explode_enum_string( $p_resolution_enum_string );
-	$enum_res_count = count( $t_res_arr );
-	$c_res_s = array();
-	for( $i = 0;$i < $enum_res_count;$i++ ) {
-		$t_res_s = explode_enum_arr( $t_res_arr[$i] );
-		$c_res_s[$i] = db_prepare_string( $t_res_s[0] );
-	}
+	# Get the resolution values ot use
+	$c_res_s = MantisEnum::getValues( $p_resolution_enum_string );
+	$enum_res_count = count( $c_res_s );
 
 	$specific_where = helper_project_specific_where( $t_project_id );
 	if( ' 1<>1' == $specific_where ) {
@@ -874,14 +867,9 @@ function summary_print_reporter_resolution( $p_resolution_enum_string ) {
 	$t_project_id = helper_get_current_project();
 	$t_user_id = auth_get_current_user_id();
 
-	# Organise an array of resolution values to be used later
-	$t_res_arr = explode_enum_string( $p_resolution_enum_string );
-	$enum_res_count = count( $t_res_arr );
-	$c_res_s = array();
-	for( $i = 0;$i < $enum_res_count;$i++ ) {
-		$t_res_s = explode_enum_arr( $t_res_arr[$i] );
-		$c_res_s[$i] = db_prepare_string( $t_res_s[0] );
-	}
+	# Get the resolution values ot use
+	$c_res_s = MantisEnum::getValues( $p_resolution_enum_string );
+	$enum_res_count = count( $c_res_s );
 
 	# Checking if it's a per project statistic or all projects
 	$specific_where = helper_project_specific_where( $t_project_id );
@@ -1006,21 +994,13 @@ function summary_print_reporter_effectiveness( $p_severity_enum_string, $p_resol
 	$t_notbug_multiplier[DUPLICATE] = 3;
 	$t_notbug_multiplier[NOT_A_BUG] = 5;
 
-	$t_sev_arr = explode_enum_string( $p_severity_enum_string );
-	$enum_sev_count = count( $t_sev_arr );
-	$c_sev_s = array();
-	for( $i = 0;$i < $enum_sev_count;$i++ ) {
-		$t_sev_s = explode_enum_arr( $t_sev_arr[$i] );
-		$c_sev_s[$i] = db_prepare_string( $t_sev_s[0] );
-	}
+	# Get the severity values ot use
+	$c_sev_s = MantisEnum::getValues( $p_severity_enum_string );
+	$enum_sev_count = count( $c_sev_s );
 
-	$t_res_arr = explode_enum_string( $p_resolution_enum_string );
-	$enum_res_count = count( $t_res_arr );
-	$c_res_s = array();
-	for( $i = 0;$i < $enum_res_count;$i++ ) {
-		$t_res_s = explode_enum_arr( $t_res_arr[$i] );
-		$c_res_s[$i] = db_prepare_string( $t_res_s[0] );
-	}
+	# Get the resolution values ot use
+	$c_res_s = MantisEnum::getValues( $p_resolution_enum_string );
+	$enum_res_count = count( $c_res_s );
 
 	# Checking if it's a per project statistic or all projects
 	$specific_where = helper_project_specific_where( $t_project_id );
diff --git a/core/utility_api.php b/core/utility_api.php
index a6dab11..4482d12 100644
--- a/core/utility_api.php
+++ b/core/utility_api.php
@@ -46,63 +46,6 @@ function trans_bool( $p_num ) {
 }
 
 /**
- * Breaks up an enum string into num:value elements
- * @param string $p_enum_string enum string
- * @return array array of num:value elements
- * @access public
- */
-function explode_enum_string( $p_enum_string ) {
-	return explode( ',', $p_enum_string );
-}
-
-/**
- * Given one num:value pair it will return both in an array
- * num will be first (element 0) value second (element 1)
- * @param string $p_enum_elem a num:value pair
- * @return array array(num->value)
- * @access public
- */
-function explode_enum_arr( $p_enum_elem ) {
-	return explode( ':', $p_enum_elem );
-}
-
-/**
- * Get the string associated with the $p_enum value
- * @param string $p_enum_string
- * @return array
- * @access public
- */
-function get_enum_to_array( $p_enum_string ) {
-	$t_arr = explode_enum_string( $p_enum_string );
-	$enum_count = count( $t_arr );
-	for( $i = 0;$i < $enum_count;$i++ ) {
-		$t_s = explode_enum_arr( $t_arr[$i] );
-		$t_index = (int) $t_s[0];
-		$t_array[$t_index] = $t_s[1];
-	}
-	return $t_array;
-}
-
-/**
- * Get the string associated with the $p_enum value
- * @param string $p_enum_string
- * @param int $p_num
- * @return string
- * @access public
- */
-function get_enum_to_string( $p_enum_string, $p_num ) {
-	$t_arr = explode_enum_string( $p_enum_string );
-	$enum_count = count( $t_arr );
-	for( $i = 0;$i < $enum_count;$i++ ) {
-		$t_s = explode_enum_arr( $t_arr[$i] );
-		if( $t_s[0] == $p_num ) {
-			return $t_s[1];
-		}
-	}
-	return '@' . $p_num . '@';
-}
-
-/**
  * Add a trailing DIRECTORY_SEPARATOR to a string if it isn't present
  * @param string $p_path
  * @return string
diff --git a/excel_xml_export.php b/excel_xml_export.php
index f9077cd..c61cf48 100644
--- a/excel_xml_export.php
+++ b/excel_xml_export.php
@@ -67,7 +67,7 @@
 	echo excel_get_header( $t_export_title );
 	echo excel_get_titles_row();
 
-	$f_bug_arr = explode_enum_string( $f_export );
+	$f_bug_arr = explode( ',', $f_export );
 
 	$t_columns = excel_get_columns();
 
diff --git a/manage_config_email_page.php b/manage_config_email_page.php
index b135f8f..72e70d5 100644
--- a/manage_config_email_page.php
+++ b/manage_config_email_page.php
@@ -140,7 +140,7 @@
 
 	function get_section_begin_for_email( $p_section_name ) {
 		global $t_project;
-		$t_access_levels = explode_enum_string( config_get( 'access_levels_enum_string' ) );
+		$t_access_levels = MantisEnum::getValues( config_get( 'access_levels_enum_string' ) );
 		echo '<table class="width100">';
 		echo '<tr><td class="form-title" colspan="' . ( count( $t_access_levels ) + 7 ) . '">' . $p_section_name . '</td></tr>' . "\n";
 		echo '<tr><td class="form-title" width="30%" rowspan="2">' . lang_get( 'message' ) . '</td>';
@@ -149,15 +149,16 @@
 		echo '<td class="form-title" style="text-align:center" rowspan="2">&nbsp;' . lang_get( 'users_monitoring_bug' ) . '&nbsp;</td>';
 		echo '<td class="form-title" style="text-align:center" rowspan="2">&nbsp;' . lang_get( 'users_added_bugnote' ) . '&nbsp;</td>';
 		echo '<td class="form-title" style="text-align:center" colspan="' . count( $t_access_levels ) . '">&nbsp;' . lang_get( 'access_levels' ) . '&nbsp;</td></tr><tr>';
+
 		foreach( $t_access_levels as $t_access_level ) {
-			$t_entry_array = explode_enum_arr( $t_access_level );
-			echo '<td class="form-title" style="text-align:center">&nbsp;' . get_enum_to_string( lang_get( 'access_levels_enum_string' ), $t_entry_array[0] ) . '&nbsp;</td>';
+			echo '<td class="form-title" style="text-align:center">&nbsp;' . MantisEnum::getLabel( lang_get( 'access_levels_enum_string' ), $t_access_level ) . '&nbsp;</td>';
 		}
+
 		echo '</tr>' . "\n";
 	}
 
 	function get_capability_row_for_email( $p_caption, $p_message_type ) {
-		$t_access_levels = explode_enum_string( config_get( 'access_levels_enum_string' ) );
+		$t_access_levels = ManisEnum::getValues( config_get( 'access_levels_enum_string' ) );
 
 		echo '<tr ' . helper_alternate_class() . '><td>' . string_display( $p_caption ) . '</td>';
 		echo '<td class="center"' . colour_notify_flag( $p_message_type, 'reporter' ) . '>' . show_notify_flag( $p_message_type, 'reporter' )  . '</td>';
@@ -166,9 +167,9 @@
 		echo '<td class="center"' . colour_notify_flag( $p_message_type, 'bugnotes' ) . '>' . show_notify_flag( $p_message_type, 'bugnotes' ) . '</td>';
 
 		foreach( $t_access_levels as $t_access_level ) {
-			$t_entry_array = explode_enum_arr( $t_access_level );
-			echo '<td class="center"' . colour_threshold_flag( (int)$t_entry_array[0], $p_message_type ) . '>' . show_notify_threshold( (int)$t_entry_array[0], $p_message_type ) . '</td>';
+			echo '<td class="center"' . colour_threshold_flag( $t_access_level, $p_message_type ) . '>' . show_notify_threshold( $t_access_level, $p_message_type ) . '</td>';
 		}
+
 		echo '</tr>' . "\n";
 	}
 
@@ -197,7 +198,7 @@
 
 	$t_actions[] = 'relationship';
 
-	$t_statuses = get_enum_to_array( config_get( 'status_enum_string' ) );
+	$t_statuses = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) );
 	foreach( $t_statuses as $t_status ) {
 		$t_actions[] =  $t_status;
 	}
@@ -267,10 +268,9 @@
 
 		get_capability_row_for_email( lang_get( 'email_on_relationship_changed' ), 'relationship' );
 
-		$t_statuses = explode_enum_string( config_get( 'status_enum_string' ) );
-		foreach( $t_statuses as $t_status ) {
-			list( $t_state, $t_label ) = explode_enum_arr( $t_status );
-			get_capability_row_for_email( lang_get( 'status_changed_to' ) . ' \'' . get_enum_element( 'status', $t_state ) . '\'', $t_label );
+		$t_statuses = MantisEnum::getValues( config_get( 'status_enum_string' ) );
+		foreach ( $t_statuses as $t_status ) {
+			get_capability_row_for_email( lang_get( 'status_changed_to' ) . ' \'' . get_enum_element( 'status', $t_status ) . '\'', $t_label );
 		}
 
 		get_section_end_for_email();
diff --git a/manage_config_email_set.php b/manage_config_email_set.php
index adc9a8d..455649f 100644
--- a/manage_config_email_set.php
+++ b/manage_config_email_set.php
@@ -58,7 +58,7 @@
 
 	$t_valid_actions[] = 'relationship';
 
-	$t_statuses = get_enum_to_array( config_get( 'status_enum_string' ) );
+	$t_statuses = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) );
     ksort( $t_statuses );
     reset( $t_statuses );
 
diff --git a/manage_config_work_threshold_page.php b/manage_config_work_threshold_page.php
index 25b4182..9580b27 100644
--- a/manage_config_work_threshold_page.php
+++ b/manage_config_work_threshold_page.php
@@ -41,7 +41,7 @@
 	$t_access = user_get_access_level( $t_user, $t_project_id );
 	$t_show_submit = false;
 
-	$t_access_levels = get_enum_to_array( config_get( 'access_levels_enum_string' ) );
+	$t_access_levels = MantisEnum::getAssocArrayIndexedByValues( config_get( 'access_levels_enum_string' ) );
 
 	$t_overrides = array();	
 	function set_overrides( $p_config ) {
@@ -60,7 +60,7 @@
 		echo '<td class="form-title"style="text-align:center"  width="40%" colspan="' . count( $t_access_levels ) . '">' . lang_get( 'access_levels' ) . '</td>';
 		echo '<td class="form-title" style="text-align:center" rowspan="2">&nbsp;' . lang_get( 'alter_level' ) . '&nbsp;</td></tr><tr>';
 		foreach( $t_access_levels as $t_access_level => $t_access_label ) {
-			echo '<td class="form-title" style="text-align:center">&nbsp;' . get_enum_to_string( lang_get( 'access_levels_enum_string' ), $t_access_level ) . '&nbsp;</td>';
+			echo '<td class="form-title" style="text-align:center">&nbsp;' . MantisEnum::getLabel( lang_get( 'access_levels_enum_string' ), $t_access_level ) . '&nbsp;</td>';
 		}
 		echo '</tr>' . "\n";
 	}
@@ -145,7 +145,7 @@
 			print_enum_string_option_list( 'access_levels', config_get_access( $p_threshold ) );
 			echo '</select> </td>';
 		} else {
-			echo '<td>' . get_enum_to_string( lang_get( 'access_levels_enum_string' ), config_get_access( $p_threshold ) ) . '&nbsp;</td>';
+			echo '<td>' . MantisEnum::getLabel( lang_get( 'access_levels_enum_string' ), config_get_access( $p_threshold ) ) . '&nbsp;</td>';
 		}
 
 		echo '</tr>' . "\n";
@@ -194,7 +194,7 @@
 			print_enum_string_option_list( 'access_levels', config_get_access( $p_threshold ) );
 			echo '</select> </td>';
 		} else {
-			echo '<td>' . get_enum_to_string( lang_get( 'access_levels_enum_string' ), config_get_access( $p_threshold ) ) . '&nbsp;</td>';
+			echo '<td>' . MantisEnum::getLabel( lang_get( 'access_levels_enum_string' ), config_get_access( $p_threshold ) ) . '&nbsp;</td>';
 		}
 
 		echo '</tr>' . "\n";
@@ -231,7 +231,7 @@
 			echo '</select></td><td colspan="' . ( count( $t_access_levels ) - 3 ) . '"></td>';
 		    $t_show_submit = true;
 		} else {
-			$t_value = get_enum_to_string( lang_get( $p_enum . '_enum_string' ), config_get( $p_threshold ) ) . '&nbsp;';
+			$t_value = MantisEnum::getLabel( lang_get( $p_enum . '_enum_string' ), config_get( $p_threshold ) ) . '&nbsp;';
 		    echo '<td class="left" colspan="3"' . $t_colour . '>' . $t_value . '</td><td colspan="' . ( count( $t_access_levels ) - 3 ) . '"></td>';
         }
 
@@ -240,7 +240,7 @@
 			print_enum_string_option_list( 'access_levels', config_get_access( $p_threshold ) );
 			echo '</select> </td>';
 		} else {
-			echo '<td>' . get_enum_to_string( lang_get( 'access_levels_enum_string' ), config_get_access( $p_threshold ) ) . '&nbsp;</td>';
+			echo '<td>' . MantisEnum::getLabel( lang_get( 'access_levels_enum_string' ), config_get_access( $p_threshold ) ) . '&nbsp;</td>';
 		}
 
 		echo '</tr>' . "\n";
diff --git a/manage_config_work_threshold_set.php b/manage_config_work_threshold_set.php
index be2fad1..e297e19 100644
--- a/manage_config_work_threshold_set.php
+++ b/manage_config_work_threshold_set.php
@@ -49,7 +49,7 @@
 	        $f_threshold = gpc_get_int_array( 'flag_thres_' . $p_threshold, array() );
 	        $f_access = gpc_get_int( 'access_' . $p_threshold );
             # @@debug @@ echo "<br />for $p_threshold "; var_dump($f_threshold, $f_access); echo '<br />';
-		    $t_access_levels = get_enum_to_array( config_get( 'access_levels_enum_string' ) );
+		    $t_access_levels = MantisEnum::getAssocArrayIndexedByValues( config_get( 'access_levels_enum_string' ) );
 		    ksort( $t_access_levels );
 		    reset( $t_access_levels );
 
diff --git a/manage_config_workflow_page.php b/manage_config_workflow_page.php
index 9467517..86b68f5 100644
--- a/manage_config_workflow_page.php
+++ b/manage_config_workflow_page.php
@@ -50,7 +50,7 @@
 	}
 
 	function parse_workflow( $p_enum_workflow ) {
-        $t_status_arr  = get_enum_to_array( config_get( 'status_enum_string' ) );
+        $t_status_arr  = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) );
         if ( 0 == count( $p_enum_workflow ) ) {
             # workflow is not set, default it to all transitions
 	        foreach ( $t_status_arr as $t_status => $t_label ) {
@@ -69,7 +69,7 @@
 
     	# prepopulate new bug state (bugs go from nothing to here)
     	$t_submit_status_array = config_get( 'bug_submit_status' );
-    	$t_new_label = get_enum_to_string( lang_get( 'status_enum_string' ), NEW_ );
+    	$t_new_label = MantisEnum::getLabel( lang_get( 'status_enum_string' ), NEW_ );
     	if ( is_array( $t_submit_status_array ) ) {
     		# @@@ (thraxisp) this is not implemented in bug_api.php
     		foreach ($t_submit_status_array as $t_access => $t_status ) {
@@ -84,12 +84,12 @@
 
         # add user defined arcs and implicit reopen arcs
     	$t_reopen = config_get( 'bug_reopen_status' );
-    	$t_reopen_label = get_enum_to_string( lang_get( 'resolution_enum_string' ), REOPENED );
+    	$t_reopen_label = MantisEnum::getLabel( lang_get( 'resolution_enum_string' ), REOPENED );
     	$t_resolved_status = config_get( 'bug_resolved_status_threshold' );
     	$t_default = array();
     	foreach ( $t_status_arr as $t_status => $t_status_label ) {
     		if ( isset( $p_enum_workflow[$t_status] ) ) {
-    			$t_next_arr = get_enum_to_array( $p_enum_workflow[$t_status] );
+    			$t_next_arr = MantisEnum::getAssocArrayIndexedByValues( $p_enum_workflow[$t_status] );
     			foreach ( $t_next_arr as $t_next => $t_next_label) {
                     if ( ! isset( $t_default[$t_status] ) ) {
     	                $t_default[$t_status] = $t_next;
@@ -159,26 +159,27 @@
 	}
 
 	function section_begin( $p_section_name ) {
-		$t_enum_status = explode_enum_string( config_get( 'status_enum_string' ) );
+		$t_enum_statuses = MantisEnum::getValues( config_get( 'status_enum_string' ) );
 		echo '<table class="width100">';
-		echo '<tr><td class="form-title" colspan="' . ( count( $t_enum_status ) + 2 ) . '">'
+		echo '<tr><td class="form-title" colspan="' . ( count( $t_enum_statuses ) + 2 ) . '">'
 			. $p_section_name . '</td></tr>' . "\n";
 		echo '<tr><td class="form-title" width="30%" rowspan="2">' . lang_get( 'current_status' ) . '</td>';
-		echo '<td class="form-title" style="text-align:center" colspan="' . ( count( $t_enum_status ) + 1 ) . '">'
+		echo '<td class="form-title" style="text-align:center" colspan="' . ( count( $t_enum_statuses ) + 1 ) . '">'
 			. lang_get( 'next_status' ) . '</td></tr>';
 		echo "\n<tr>";
-		foreach( $t_enum_status as $t_status ) {
-			$t_entry_array = explode_enum_arr( $t_status );
-			echo '<td class="form-title" style="text-align:center">&nbsp;' . string_no_break( get_enum_to_string( lang_get( 'status_enum_string' ), $t_entry_array[0] ) ) . '&nbsp;</td>';
+
+		foreach( $t_enum_statuses as $t_status ) {
+			echo '<td class="form-title" style="text-align:center">&nbsp;' . string_no_break( MantisEnum::getLabel( lang_get( 'status_enum_string' ), $t_status ) ) . '&nbsp;</td>';
 		}
-			echo '<td class="form-title" style="text-align:center">' . lang_get( 'custom_field_default_value' ) . '</td>';
+
+		echo '<td class="form-title" style="text-align:center">' . lang_get( 'custom_field_default_value' ) . '</td>';
 		echo '</tr>' . "\n";
 	}
 
 	function capability_row( $p_from_status ) {
 		global $t_file_workflow, $t_global_workflow, $t_project_workflow, $t_colour_global, $t_colour_project, $t_can_change_workflow;
-		$t_enum_status = get_enum_to_array( config_get( 'status_enum_string' ) );
-		echo '<tr ' . helper_alternate_class() . '><td>' . string_no_break( get_enum_to_string( lang_get( 'status_enum_string' ), $p_from_status ) ) . '</td>';
+		$t_enum_status = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) );
+		echo '<tr ' . helper_alternate_class() . '><td>' . string_no_break( MantisEnum::getLabel( lang_get( 'status_enum_string' ), $p_from_status ) ) . '</td>';
 		foreach ( $t_enum_status as $t_to_status_id => $t_to_status_label ) {
 			echo show_flag( $p_from_status, $t_to_status_id );
 		}
@@ -206,7 +207,7 @@
             print_enum_string_option_list( 'status', $t_project );
             echo '</select>';
         } else {
-            echo get_enum_to_string( lang_get( 'status_enum_string' ), $t_project );
+            echo MantisEnum::getLabel( lang_get( 'status_enum_string' ), $t_project );
         }
         echo ' </td>';
 		echo '</tr>' . "\n";
@@ -256,8 +257,8 @@
 			echo '</select> </td>';
 			$t_can_change_flags = true;
 		} else {
-			echo '<td' . $t_colour . '>' . get_enum_to_string( lang_get( 'status_enum_string' ), $t_project ) . '&nbsp;</td>';
-			echo '<td>' . get_enum_to_string( lang_get( 'access_levels_enum_string' ), config_get_access( $p_threshold ) ) . '&nbsp;</td>';
+			echo '<td' . $t_colour . '>' . MantisEnum::getLabel( lang_get( 'status_enum_string' ), $t_project ) . '&nbsp;</td>';
+			echo '<td>' . MantisEnum::getLabel( lang_get( 'access_levels_enum_string' ), config_get_access( $p_threshold ) ) . '&nbsp;</td>';
 		}
 
 		echo '</tr>' . "\n";
@@ -268,7 +269,6 @@
 	}
 
 	function access_begin( $p_section_name ) {
-		$t_enum_status = explode_enum_string( config_get( 'status_enum_string' ) );
 		echo '<table class="width100">';
 		echo '<tr><td class="form-title" colspan="2">'
 			. $p_section_name . '</td></tr>' . "\n";
@@ -278,7 +278,7 @@
 	function access_row() {
 		global $t_access, $t_can_change_flags, $t_colour_project, $t_colour_global;
 
-		$t_enum_status = get_enum_to_array( config_get( 'status_enum_string' ) );
+		$t_enum_status = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) );
 
 		$t_file_new = config_get_global( 'report_bug_threshold' );
 		$t_global_new = config_get( 'report_bug_threshold', null, null, ALL_PROJECTS );
@@ -306,7 +306,7 @@
 		}
 
 		foreach ( $t_enum_status as $t_status => $t_status_label) {
-			echo '<tr ' . helper_alternate_class() . '><td width="30%">' . string_no_break( get_enum_to_string( lang_get( 'status_enum_string' ), $t_status ) ) . '</td>';
+			echo '<tr ' . helper_alternate_class() . '><td width="30%">' . string_no_break( MantisEnum::getLabel( lang_get( 'status_enum_string' ), $t_status ) ) . '</td>';
 			if ( NEW_ == $t_status ) {
 				$t_level = $t_project_new;
 				$t_can_change = ( $t_access >= config_get_access( 'report_bug_threshold' ) );
@@ -348,7 +348,7 @@
 				echo '</select> </td>';
 			    $t_can_change_flags = true;
 			} else {
-				echo '<td class="center"' . $t_colour . '>' . get_enum_to_string( lang_get( 'access_levels_enum_string' ), $t_level ) . '</td>';
+				echo '<td class="center"' . $t_colour . '>' . MantisEnum::getLabel( lang_get( 'access_levels_enum_string' ), $t_level ) . '</td>';
 			}
 			echo '</tr>' . "\n";
 		}
@@ -358,7 +358,7 @@
 
 	# count arcs in and out of each status
 	$t_enum_status = config_get( 'status_enum_string' );
-	$t_status_arr  = get_enum_to_array( $t_enum_status );
+	$t_status_arr  = MantisEnum::getAssocArrayIndexedByValues( $t_enum_status );
 
 	$t_extra_enum_status = '0:non-existent,' . $t_enum_status;
 	$t_lang_enum_status = '0:' . lang_get( 'non_existent' ) . ',' . lang_get( 'status_enum_string' );
@@ -374,7 +374,7 @@
 	foreach ( $t_status_arr as $t_status => $t_label ) {
 		if ( isset( $t_project_workflow['exit'][$t_status][$t_status] ) ) {
 			$t_validation_result .= '<tr ' . helper_alternate_class() . '><td>'
-							. get_enum_to_string( $t_lang_enum_status, $t_status )
+							. MantisEnum::getLabel( $t_lang_enum_status, $t_status )
 							. '</td><td bgcolor="#FFED4F">' . lang_get( 'superfluous' ) . '</td>';
 		}
 	}
@@ -383,7 +383,7 @@
 	foreach ( $t_status_arr as $t_status => $t_status_label) {
 		if ( ( 0 == count( $t_project_workflow['entry'][$t_status] ) ) && ( 0 < count( $t_project_workflow['exit'][$t_status] ) ) ){
 			$t_validation_result .= '<tr ' . helper_alternate_class() . '><td>'
-							. get_enum_to_string( $t_lang_enum_status, $t_status )
+							. MantisEnum::getLabel( $t_lang_enum_status, $t_status )
 							. '</td><td bgcolor="#FF0088">' . lang_get( 'unreachable' ) . '</td>';
 		}
 	}
@@ -392,7 +392,7 @@
 	foreach ( $t_status_arr as $t_status => $t_status_label ) {
 		if ( ( 0 == count( $t_project_workflow['exit'][$t_status] ) ) && ( 0 < count( $t_project_workflow['entry'][$t_status] ) ) ){
 			$t_validation_result .= '<tr ' . helper_alternate_class() . '><td>'
-							. get_enum_to_string( $t_lang_enum_status, $t_status )
+							. MantisEnum::getLabel( $t_lang_enum_status, $t_status )
 							. '</td><td bgcolor="#FF0088">' . lang_get( 'no_exit' ) . '</td>';
 		}
 	}
@@ -401,7 +401,7 @@
 	foreach ( $t_status_arr as $t_status => $t_status_label ) {
 		if ( ( 0 == count( $t_project_workflow['exit'][$t_status] ) ) && ( 0 == count( $t_project_workflow['entry'][$t_status] ) ) ){
 			$t_validation_result .= '<tr ' . helper_alternate_class() . '><td>'
-							. get_enum_to_string( $t_lang_enum_status, $t_status )
+							. MantisEnum::getLabel( $t_lang_enum_status, $t_status )
 							. '</td><td bgcolor="#FF0088">' . lang_get( 'unreachable' ) . '<br />' . lang_get( 'no_exit' ) . '</td>';
 		}
 	}
diff --git a/manage_config_workflow_set.php b/manage_config_workflow_set.php
index a81d8e2..1200aed 100644
--- a/manage_config_workflow_set.php
+++ b/manage_config_workflow_set.php
@@ -66,7 +66,7 @@
 			list( $t_from, $t_to ) = split( ':', $t_transition );
 			$t_matrix[$t_from][$t_to] = '';
 		}
-		$t_statuses = get_enum_to_array( config_get( 'status_enum_string' ) );
+		$t_statuses = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) );
 		foreach( $t_statuses as $t_state => $t_label) {
 			$t_workflow_row = '';
 			$t_default = gpc_get_int( 'default_' . $t_state );
@@ -103,7 +103,7 @@
 		$f_access = gpc_get( 'status_access' );
 
 		# walk through the status labels to set the status threshold
-		$t_enum_status = explode_enum_string( config_get( 'status_enum_string' ) );
+		$t_enum_status = explode( ',', config_get( 'status_enum_string' ) );
 		$t_set_status = array();
 		foreach( $t_statuses as $t_status_id => $t_status_label) {
 			$f_level = gpc_get( 'access_change_' . $t_status_id );
diff --git a/print_all_bug_page_word.php b/print_all_bug_page_word.php
index 45d9342..0127570 100644
--- a/print_all_bug_page_word.php
+++ b/print_all_bug_page_word.php
@@ -85,7 +85,7 @@ xmlns="http://www.w3.org/TR/REC-html40">
 <?php html_body_begin() ?>
 
 <?php
-	$f_bug_arr = explode_enum_string( $f_export );
+	$f_bug_arr = explode( ',', $f_export );
 	$t_count_exported = 0;
 
 	for( $j=0; $j < $t_row_count; $j++ ) {
diff --git a/summary_page.php b/summary_page.php
index 7d96b27..1546c89 100644
--- a/summary_page.php
+++ b/summary_page.php
@@ -360,20 +360,13 @@
 				<?php echo lang_get( 'reporter_by_resolution' ) ?>
 			</td>
 			<?php
-			$t_arr = explode_enum_string( config_get( 'resolution_enum_string' ) );
-			$enum_count = count( $t_arr );
-
-			for ($i=0;$i<$enum_count;$i++) {
-				print '<td>';
-				$t_s = explode_enum_arr( $t_arr[$i] );
-				$c_s[0] = db_prepare_string( $t_s[0] );
-				echo get_enum_element( 'resolution', $c_s[0] );
-				print '</td>';
+			$t_resolutions = MantisEnum::getValues( config_get( 'resolution_enum_string' ) );
+
+			foreach ( $t_resolutions as $t_resolution ) {
+				echo '<td>', get_enum_element( 'resolution', $t_resolution ), '</td>';
 			}
 
-			print '<td>';
-			print lang_get( 'percentage_errors' );
-			print '</td>';
+			echo '<td>', lang_get( 'percentage_errors' ), '</td>';
 			?>
 		</tr>
 		<?php summary_print_reporter_resolution( config_get( 'resolution_enum_string' ) ) ?>
@@ -390,20 +383,13 @@
 				<?php echo lang_get( 'developer_by_resolution' ) ?>
 			</td>
 			<?php
-			$t_arr = explode_enum_string( config_get( 'resolution_enum_string' ) );
-			$enum_count = count( $t_arr );
-
-			for ($i=0;$i<$enum_count;$i++) {
-				print '<td>';
-				$t_s = explode_enum_arr( $t_arr[$i] );
-				$c_s[0] = db_prepare_string( $t_s[0] );
-				echo get_enum_element( 'resolution', $c_s[0] );
-				print '</td>';
+			$t_resolutions = MantisEnum::getValues( config_get( 'resolution_enum_string' ) );
+
+			foreach ( $t_resolutions as $t_resolution ) {
+				echo '<td>', get_enum_element( 'resolution', $t_resolution ), '</td>';
 			}
 
-			print '<td>';
-			print lang_get( 'percentage_fixed' );
-			print '</td>';
+			echo '<td>', lang_get( 'percentage_fixed' ), '</td>';
 			?>
 		</tr>
 		<?php summary_print_developer_resolution( config_get( 'resolution_enum_string' ) ) ?>
diff --git a/tests/MantisEnumTest.php b/tests/MantisEnumTest.php
new file mode 100644
index 0000000..43009cf
--- /dev/null
+++ b/tests/MantisEnumTest.php
@@ -0,0 +1,103 @@
+<?php
+/*
+ * Created on Dec 1, 2008
+ *
+ * To change the template for this generated file go to
+ * Window - Preferences - PHPeclipse - PHP - Code Templates
+ */
+
+require_once 'PHPUnit/Framework.php';
+
+$t_root_path = dirname( dirname( __FILE__ ) )  . DIRECTORY_SEPARATOR;
+require_once $t_root_path . 'core/classes/MantisEnum.class.php';
+
+/**
+ * Test cases for MantisEnum class.
+ */
+class MantisEnumTest extends PHPUnit_Framework_TestCase
+{
+	const ACCESS_LEVELS_ENUM = '10:viewer,25:reporter,40:updater,55:developer,70:manager,90:administrator';
+	const EMPTY_ENUM = '';
+	const DUPLICATE_VALUES_ENUM = '10:viewer1,10:viewer2';
+	const DUPLICATE_LABELS_ENUM = '10:viewer,20:viewer';
+	const SINGLE_VALUE_ENUM = '10:viewer';
+	const NAME_WITH_SPACES_ENUM = '10:first label,20:second label';
+	const NON_TRIMMED_ENUM = '10 : viewer, 20 : reporter';
+
+	/**
+	 * Standard tests against a valid enum.
+	 */
+    public function testGetStringFromValue()
+    {    	
+        $this->assertEquals( 'viewer', MantisEnum::getLabel( MantisEnumTest::ACCESS_LEVELS_ENUM, 10 ) );
+        $this->assertEquals( 'reporter', MantisEnum::getLabel( MantisEnumTest::ACCESS_LEVELS_ENUM, 25 ) );
+        $this->assertEquals( 'updater', MantisEnum::getLabel( MantisEnumTest::ACCESS_LEVELS_ENUM, 40 ) );
+        $this->assertEquals( 'developer', MantisEnum::getLabel( MantisEnumTest::ACCESS_LEVELS_ENUM, 55 ) );
+        $this->assertEquals( 'manager', MantisEnum::getLabel( MantisEnumTest::ACCESS_LEVELS_ENUM, 70 ) );
+        $this->assertEquals( 'administrator', MantisEnum::getLabel( MantisEnumTest::ACCESS_LEVELS_ENUM, 90 ) );
+        $this->assertEquals( '@100@', MantisEnum::getLabel( MantisEnumTest::ACCESS_LEVELS_ENUM, 100 ) );
+        $this->assertEquals( '@-1@', MantisEnum::getLabel( MantisEnumTest::ACCESS_LEVELS_ENUM, -1 ) );
+    }
+    
+    public function testGetValues()
+    {
+        $this->assertEquals( array( 10, 25, 40, 55, 70,90 ), MantisEnum::getValues( MantisEnumTest::ACCESS_LEVELS_ENUM, 10 ) );
+        $this->assertEquals( array(), MantisEnum::getValues( MantisEnumTest::EMPTY_ENUM, 10 ) );
+    }
+
+	/**
+	 * Tests against an empty enum
+	 */
+    public function testEmptyEnum()
+    {    	
+        $this->assertEquals( '@10@', MantisEnum::getLabel( MantisEnumTest::EMPTY_ENUM, 10 ) );
+    }
+
+	/**
+	 * Tests enumerations that contain duplicate values.
+	 */
+    public function testDuplicateValuesEnum()
+    {    	
+        $this->assertEquals( 'viewer1', MantisEnum::getLabel( MantisEnumTest::DUPLICATE_VALUES_ENUM, 10 ) );
+        $this->assertEquals( '@100@', MantisEnum::getLabel( MantisEnumTest::DUPLICATE_VALUES_ENUM, 100 ) );
+    }
+
+	/**
+	 * Tests enumerations that contain duplicate labels.
+	 */
+    public function testDuplicateLabelsValuesEnum()
+    {    	
+        $this->assertEquals( 'viewer', MantisEnum::getLabel( MantisEnumTest::DUPLICATE_LABELS_ENUM, 10 ) );
+        $this->assertEquals( 'viewer', MantisEnum::getLabel( MantisEnumTest::DUPLICATE_LABELS_ENUM, 20 ) );
+        $this->assertEquals( '@100@', MantisEnum::getLabel( MantisEnumTest::DUPLICATE_LABELS_ENUM, 100 ) );
+    }
+
+	/**
+	 * Tests enumerations with a single tuple.
+	 */
+    public function testSingleValueEnum()
+    {    	
+        $this->assertEquals( 'viewer', MantisEnum::getLabel( MantisEnumTest::SINGLE_VALUE_ENUM, 10 ) );
+        $this->assertEquals( '@100@', MantisEnum::getLabel( MantisEnumTest::SINGLE_VALUE_ENUM, 100 ) );
+    }
+
+	/**
+	 * Tests enumerations with labels that contain spaces.
+	 */
+    public function testNameWithSpacesEnum()
+    {    	
+        $this->assertEquals( 'first label', MantisEnum::getLabel( MantisEnumTest::NAME_WITH_SPACES_ENUM, 10 ) );
+        $this->assertEquals( 'second label', MantisEnum::getLabel( MantisEnumTest::NAME_WITH_SPACES_ENUM, 20 ) );
+        $this->assertEquals( '@100@', MantisEnum::getLabel( MantisEnumTest::NAME_WITH_SPACES_ENUM, 100 ) );
+    }
+    
+	/**
+	 * Tests enumerations that contain duplicate labels.
+	 */
+    public function testNonTrimmedEnum()
+    {    	
+        $this->assertEquals( 'viewer', MantisEnum::getLabel( MantisEnumTest::NON_TRIMMED_ENUM, 10 ) );
+        $this->assertEquals( 'reporter', MantisEnum::getLabel( MantisEnumTest::NON_TRIMMED_ENUM, 20 ) );
+        $this->assertEquals( '@100@', MantisEnum::getLabel( MantisEnumTest::NON_TRIMMED_ENUM, 100 ) );
+    }
+}
enums_ut_01.patch (60,129 bytes)   
enums_ut_02.patch (59,540 bytes)   
From 6fad70b1137eab134a1ffb3c08445f8809de9bfa Mon Sep 17 00:00:00 2001
From: Victor Boctor <vboctor@gmail.com>
Date: Tue, 9 Dec 2008 21:40:20 -0800
Subject: [PATCH] Fixes #9946: Refactor enumeration handling and add unit tests for it.


diff --git a/adm_permissions_report.php b/adm_permissions_report.php
index 751695b..2be70d4 100644
--- a/adm_permissions_report.php
+++ b/adm_permissions_report.php
@@ -37,27 +37,27 @@
 	print_manage_config_menu( 'adm_permissions_report.php' );
 
 	function get_section_begin( $p_section_name ) {
-		$t_access_levels = explode_enum_string( config_get( 'access_levels_enum_string' ) );
+		$t_access_levels = MantisEnum::getValues( config_get( 'access_levels_enum_string' ) );
+
 		$t_output = '<table class="width100">';
 		$t_output .= '<tr><td class="form-title" colspan="' . ( count( $t_access_levels ) + 1 ) . '">' . strtoupper( $p_section_name ) . '</td></tr>' . "\n";
 		$t_output .= '<tr><td class="form-title" width="40%">' . lang_get( 'perm_rpt_capability' ) . '</td>';
+
 		foreach( $t_access_levels as $t_access_level ) {
-			$t_entry_array = explode_enum_arr( $t_access_level );
-			$t_output .= '<td class="form-title" style="text-align:center">&nbsp;' . get_enum_to_string( lang_get( 'access_levels_enum_string' ), $t_entry_array[0] ) . '&nbsp;</td>';
+			$t_output .= '<td class="form-title" style="text-align:center">&nbsp;' . MantisEnum::getLabel( lang_get( 'access_levels_enum_string' ), $t_access_level ) . '&nbsp;</td>';
 		}
+
 		$t_output .= '</tr>' . "\n";
 
 		return $t_output;
 	}
 
 	function get_capability_row( $p_caption, $p_access_level ) {
-		$t_access_levels = explode_enum_string( config_get( 'access_levels_enum_string' ) );
+		$t_access_levels = MantisEnum::getValues( config_get( 'access_levels_enum_string' ) );
 
 		$t_output = '<tr ' . helper_alternate_class() . '><td>' . string_display( $p_caption ) . '</td>';
 		foreach( $t_access_levels as $t_access_level ) {
-			$t_entry_array = explode_enum_arr( $t_access_level );
-
-			if ( (int)$t_entry_array[0] >= (int)$p_access_level ) {
+			if ( $t_access_level >= (int)$p_access_level ) {
 				$t_value = '<img src="images/ok.gif" width="20" height="15" alt="X" title="X" />';
 			} else {
 				$t_value = '&nbsp;';
diff --git a/api/soap/mc_api.php b/api/soap/mc_api.php
index 80d4fd4..a6a98fc 100644
--- a/api/soap/mc_api.php
+++ b/api/soap/mc_api.php
@@ -189,21 +189,10 @@ function mci_get_mantis_path() {
 
 # Given a enum string and num, return the appropriate localized string
 function mci_get_enum_element( $p_enum_name, $p_val, $p_lang ) {
-	$config_var = config_get( $p_enum_name . '_enum_string' );
-	$string_var = lang_get( $p_enum_name . '_enum_string', $p_lang );
-
-	# use the global enum string to search
-	$t_arr = explode_enum_string( $config_var );
-	$t_arr_count = count( $t_arr );
-	for( $i = 0;$i < $t_arr_count;$i++ ) {
-		$elem_arr = explode_enum_arr( $t_arr[$i] );
-		if( $elem_arr[0] == $p_val ) {
-
-			# now get the appropriate translation
-			return get_enum_to_string( $string_var, $p_val );
-		}
-	}
-	return '@' . $p_val . '@';
+	$t_enum_string = config_get( $p_enum_name . '_enum_string' );
+	$t_localized_enum_string = lang_get( $p_enum_name . '_enum_string', $p_lang );
+
+	return MantisEnum::getLocalizedLabel( $t_enum_string, $t_localized_enum_string, $p_val );
 }
 
 # Gets the sub-projects that are accessible to the specified user / project.
diff --git a/api/soap/mc_enum_api.php b/api/soap/mc_enum_api.php
index 0df3f03..bff6f74 100644
--- a/api/soap/mc_enum_api.php
+++ b/api/soap/mc_enum_api.php
@@ -169,13 +169,18 @@ function mci_explode_to_objectref( $p_config_enum_string ) {
 	if( get_class( $p_config_enum_string ) == 'soap_fault' ) {
 		return $p_config_enum_string;
 	}
-	foreach( explode_enum_string( $p_config_enum_string ) as $t_enum_element ) {
-		list( $t_id, $t_name ) = explode_enum_arr( $t_enum_element );
+	
+	$t_result = array();
+
+	$t_assoc_array = MantisEnum::getAssocArrayIndexedByValues( $p_config_enum_string );
+
+	foreach ( $t_assoc_array as $t_id => $t_name ) {
 		$t_result[] = array(
 			'id' => $t_id,
 			'name' => $t_name,
 		);
-	};
+	}
+
 	return $t_result;
 }
 
@@ -203,17 +208,12 @@ function mci_enum_get_array_by_id( $p_enum_id, $p_enum_type, $p_lang ) {
  * @return The id corresponding to the given label, or 0 if not found.
  */
 function mci_get_enum_value_from_label( $p_enum_string, $p_label ) {
-	$t_arr = explode_enum_string( $p_enum_string );
-	$enum_count = count( $t_arr );
-
-	for( $i = 0;$i < $enum_count;$i++ ) {
-		$t_s = explode_enum_arr( $t_arr[$i] );
-		if( $t_s[1] == $p_label ) {
-			return $t_s[0];
-		}
+	$t_value = MantisEnum::getValue( $p_enum_string, $p_label );
+	if ( $t_value === false ) {
+		return 0;
 	}
-
-	return 0;
+	
+	return $t_value;
 }
 
 /**
diff --git a/bug_change_status_page.php b/bug_change_status_page.php
index da763ff..df8286c 100644
--- a/bug_change_status_page.php
+++ b/bug_change_status_page.php
@@ -80,7 +80,7 @@
 		}
 	}
 
-	$t_status_label = str_replace( " ", "_", get_enum_to_string( config_get( 'status_enum_string' ), $f_new_status ) );
+	$t_status_label = str_replace( " ", "_", MantisEnum::getLabel( config_get( 'status_enum_string' ), $f_new_status ) );
 	$t_resolved = config_get( 'bug_resolved_status_threshold' );
 
 	$t_bug = bug_get( $f_bug_id );
diff --git a/bug_graph_bystatus.php b/bug_graph_bystatus.php
index 5230aeb..2850a65 100644
--- a/bug_graph_bystatus.php
+++ b/bug_graph_bystatus.php
@@ -74,8 +74,8 @@
 	$t_start = $t_interval->get_start_timestamp();
 	
 	// grab all status levels
-	$t_status_arr  = get_enum_to_array( config_get( 'status_enum_string' ) );
-	$t_status_labels  = get_enum_to_array( lang_get( 'status_enum_string' ) );
+	$t_status_arr  = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) );
+	$t_status_labels  = MantisEnum::getAssocArrayIndexedByValues( lang_get( 'status_enum_string' ) );
     
     $t_bug = array();
     $t_view_status = array();
diff --git a/core.php b/core.php
index a0d583d..fce04ee 100644
--- a/core.php
+++ b/core.php
@@ -82,8 +82,20 @@
 	$t_core_path = dirname(__FILE__).DIRECTORY_SEPARATOR.'core'.DIRECTORY_SEPARATOR;
 	if (isset($GLOBALS['g_core_path']) && !isset( $HTTP_GET_VARS['g_core_path'] ) && !isset( $HTTP_POST_VARS['g_core_path'] ) && !isset( $HTTP_COOKIE_VARS['g_core_path'] ) ) {
 		$t_core_path = $g_core_path;
-	}	
+	}
+	
+	$g_core_path = $t_core_path;
+
+	# Define an autoload function to automatically load classes when referenced.
+	function __autoload( $className ) {
+		global $g_core_path;
 
+		$t_require_path = $g_core_path . 'classes' . DIRECTORY_SEPARATOR . $className . '.class.php';
+
+		if ( file_exists( $t_require_path ) ) {
+			require_once( $t_require_path );
+		}
+	}
 
 	if ( ($t_output = ob_get_contents()) != '') {
 		echo 'Possible Whitespace/Error in Configuration File - Aborting. Output so far follows:<br />';
diff --git a/core/bug_api.php b/core/bug_api.php
index bfdd52f..bfaf58c 100644
--- a/core/bug_api.php
+++ b/core/bug_api.php
@@ -449,30 +449,16 @@ function bug_check_workflow( $p_bug_status, $p_wanted_status ) {
 		# workflow not defined, use default enum
 		return true;
 	}
-	elseif( $p_bug_status == $p_wanted_status ) {
 
+	if ( $p_bug_status == $p_wanted_status ) {
 		# no change in state, allow the transition
 		return true;
-	} else {
-		# workflow defined - find allowed states
-		$t_allowed_states = $t_status_enum_workflow[$p_bug_status];
-		$t_arr = explode_enum_string( $t_allowed_states );
-
-		$t_enum_count = count( $t_arr );
-
-		for( $i = 0;$i < $t_enum_count;$i++ ) {
-
-			# check if wanted status is allowed
-			$t_elem = explode_enum_arr( $t_arr[$i] );
-			if( $p_wanted_status == $t_elem[0] ) {
-				return true;
-			}
-		}
-
-		# end for
 	}
 
-	return false;
+	# workflow defined - find allowed states
+	$t_allowed_states = $t_status_enum_workflow[$p_bug_status];
+
+	return MantisEnum::hasValue( $t_allowed_states, $p_wanted_status );
 }
 
 # ===================================
@@ -1137,7 +1123,7 @@ function bug_update( $p_bug_id, $p_bug_data, $p_update_extended = false, $p_bypa
 
 		# status changed
 		if( $t_old_data->status != $p_bug_data->status ) {
-			$t_status = get_enum_to_string( config_get( 'status_enum_string' ), $p_bug_data->status );
+			$t_status = MantisEnum::getLabel( config_get( 'status_enum_string' ), $p_bug_data->status );
 			$t_status = str_replace( ' ', '_', $t_status );
 			email_generic( $p_bug_id, $t_status, $t_status_prefix . $t_status );
 			return true;
diff --git a/core/classes/MantisEnum.class.php b/core/classes/MantisEnum.class.php
new file mode 100644
index 0000000..60a2953
--- /dev/null
+++ b/core/classes/MantisEnum.class.php
@@ -0,0 +1,206 @@
+<?php
+# Mantis - a php based bugtracking system
+
+# Mantis is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# Mantis is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Mantis.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * @package MantisBT
+ * @copyright Copyright (C) 2000 - 2009  Mantis Team - mantisbt-dev@lists.sourceforge.net
+ * @link http://www.mantisbt.org
+ */
+
+/**
+ * A class that handles Mantis Enumerations.
+ * 
+ * For example: 10:lablel1,20:label2
+ */
+class MantisEnum {
+	/**
+	 * Separator that is used to separate the enum values from their labels.
+	 */
+	const VALUE_LABEL_SEPARATOR = ':';
+	
+	/**
+	 * Separator that is used to separate the enum tuples within an enumeration definition.
+	 */
+	const TUPLE_SEPARATOR = ',';
+
+	/**
+	 * Get the string associated with the $p_enum value
+	 *
+	 * @param string $enumString
+	 * @param int $value
+	 * @return string
+	 */
+	public static function getLabel( $enumString, $value ) {
+		$assocArray = MantisEnum::getAssocArrayIndexedByValues( $enumString );
+		$valueAsInteger = (int)$value;
+
+		if ( isset( $assocArray[$valueAsInteger] ) ) {
+			return $assocArray[$valueAsInteger];
+		}
+
+		return MantisEnum::getLabelForUnknownValue( $valueAsInteger );
+	}
+
+	/**
+	 * Gets the localized label corresponding to a value.  Note that this method
+	 * takes in the standard / localized enums so that if the value is in the localized
+	 * enum but not the standard one, then it returns not found.
+	 * 
+	 * @param string $enumString The standard enum string.
+	 * @param string $localizedEnumString  The localized enum string.
+	 * @param integer $value  The value to lookup.
+	 * 
+	 * @return the label or the decorated value to represent not found.
+	 */	
+	public static function getLocalizedLabel( $enumString, $localizedEnumString, $value ) {
+		if ( !MantisEnum::hasValue( $enumString, $value ) ) {
+			return MantisEnum::getLabelForUnknownValue( $value );
+		}
+		
+		return MantisEnum::getLabel( $localizedEnumString, $value );
+	}
+	
+	/**
+	 * Gets the value associated with the specified label.
+	 * 
+	 * @param string $enumString  The enumerated string.
+	 * @param string $label       The label to map.
+	 * @return integer value of the enum or false if not found.
+	 */
+	public static function getValue( $enumString, $label ) {
+		$assocArrayByLabels = MantisEnum::getAssocArrayIndexedByLabels( $enumString );
+
+		if ( isset( $assocArrayByLabels[$label] ) ) {
+			return $assocArrayByLabels[$label];
+		}
+
+		return false;
+	}
+
+	/**
+	 * Get an associate array for the tuples of the enum where the values
+	 * are the array indices and the labels are the array values.
+	 *
+	 * @param string $enumString
+	 * @return associate array indexed by labels.
+	 */
+	public static function getAssocArrayIndexedByValues( $enumString ) {
+		$tuples = MantisEnum::getArrayOfTuples( $enumString );
+		$tuplesCount = count( $tuples );
+		
+		$assocArray = array();
+
+		foreach ( $tuples as $tuple ) {
+			$tupleTokens = MantisEnum::getArrayForTuple( $tuple );
+
+			# if not a proper tuple, skip.
+			if ( count( $tupleTokens ) != 2 ) {
+				continue;
+			}
+
+			$value = (int) trim( $tupleTokens[0] );
+
+			# if already set, skip.
+			if ( isset( $assocArray[ $value ] ) ) {
+				continue;
+			}
+			
+			$label = trim( $tupleTokens[1] );
+
+			$assocArray[$value] = $label;
+		}
+
+		return $assocArray;
+	}
+	
+	/**
+	 * Get an associate array for the tuples of the enum where the labels
+	 * are the array indices and the values are the array values.
+	 *
+	 * @param string $enumString
+	 * @return associate array indexed by labels.
+	 */
+	public static function getAssocArrayIndexedByLabels( $enumString ) {
+		return array_flip( MantisEnum::getAssocArrayIndexedByValues( $enumString ) );
+	}
+
+	/**
+	 * Gets an array with all values in the enum.
+	 * 
+	 * @param $enumString
+	 * @return array of unique values.
+	 */
+	public static function getValues( $enumString ) {
+		return array_unique( array_keys( MantisEnum::getAssocArrayIndexedByValues( $enumString ) ) );
+	}
+
+	/**
+	 * Checks if the specified enum string contains the specified value.
+	 * 
+	 * @param string $enumString  The enumeration string.
+	 * @param integer $value      The value to chec,
+	 * @return bool true if found, false otherwise.
+	 */	
+	public static function hasValue( $enumString, $value ) {
+		$assocArray = MantisEnum::getAssocArrayIndexedByValues( $enumString );	
+		$valueAsInteger = (int)$value;
+		return isset( $assocArray[$valueAsInteger] );
+	}
+
+	/**
+	 * Breaks up an enum string into num:value elements
+	 *
+	 * @param string $enumString enum string
+	 * @return array array of num:value elements
+	 */
+	private static function getArrayOfTuples( $enumString ) {
+		if ( strlen( trim( $enumString ) ) == 0 ) {
+			return array();			
+		}
+
+		$rawArray = explode( MantisEnum::TUPLE_SEPARATOR, $enumString );
+		$trimmedArray = array();
+
+		foreach ( $rawArray as $tuple ) {
+			$trimmedArray[] = trim( $tuple );
+		}
+
+		return $trimmedArray;
+	}
+
+	/**
+	 * Given one num:value pair it will return both in an array
+	 * num will be first (element 0) value second (element 1)
+	 *
+	 * @param string $tuple a num:value pair
+	 * @return array array(value, label)
+	 */
+	private function getArrayForTuple( $tuple ) {
+		return explode( MantisEnum::VALUE_LABEL_SEPARATOR, $tuple );
+	}
+
+	/**
+	 * Given a value it decorates it and returns it as the label.
+	 * 
+	 * @param integer The value (e.g. 50).
+	 * @return The decorated value (e.g. @50@).
+	 */
+	private static function getLabelForUnknownValue( $value ) {
+		$valueAsInteger = (int)$value;
+		return '@' . $valueAsInteger . '@';
+	}
+}
+?>
\ No newline at end of file
diff --git a/core/email_api.php b/core/email_api.php
index eeac195..521d27b 100644
--- a/core/email_api.php
+++ b/core/email_api.php
@@ -332,7 +332,7 @@ function email_collect_recipients( $p_bug_id, $p_notify_type, $p_extra_user_ids_
 	#  get list of status values that are not covered specifically in the prefs
 	#  These are handled by email_on_status generically
 	#  @@@ thraxisp note that email_on_assigned was co-opted to handle change in handler
-	$t_status_change = get_enum_to_array( config_get( 'status_enum_string' ) );
+	$t_status_change = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) );
 	unset( $t_status_change[NEW_] );
 	unset( $t_status_change[FEEDBACK] );
 	unset( $t_status_change[RESOLVED] );
diff --git a/core/file_api.php b/core/file_api.php
index a36a04c..32e1464 100644
--- a/core/file_api.php
+++ b/core/file_api.php
@@ -532,7 +532,7 @@ function file_type_check( $p_file_name ) {
 	$t_extension = $t_ext_array[$last_position];
 
 	# check against disallowed files
-	$t_disallowed_arr = explode_enum_string( $t_disallowed_files );
+	$t_disallowed_arr = explode( ',', $t_disallowed_files );
 	foreach( $t_disallowed_arr as $t_val ) {
 		if( 0 == strcasecmp( $t_val, $t_extension ) ) {
 			return false;
@@ -545,7 +545,7 @@ function file_type_check( $p_file_name ) {
 	}
 
 	# check against allowed files
-	$t_allowed_arr = explode_enum_string( $t_allowed_files );
+	$t_allowed_arr = explode( ',', $t_allowed_files );
 	foreach( $t_allowed_arr as $t_val ) {
 		if( 0 == strcasecmp( $t_val, $t_extension ) ) {
 			return true;
diff --git a/core/filter_api.php b/core/filter_api.php
index 71091a5..709ce27 100644
--- a/core/filter_api.php
+++ b/core/filter_api.php
@@ -1256,13 +1256,8 @@ function filter_get_bug_rows( &$p_page_number, &$p_per_page, &$p_page_count, &$p
 	# show / hide status
 	# take a list of all available statuses then remove the ones that we want hidden, then make sure
 	# the ones we want shown are still available
-	$t_status_arr = explode_enum_string( config_get( 'status_enum_string' ) );
-	$t_available_statuses = array();
 	$t_desired_statuses = array();
-	foreach( $t_status_arr as $t_this_status ) {
-		$t_this_status_arr = explode_enum_arr( $t_this_status );
-		$t_available_statuses[] = $t_this_status_arr[0];
-	}
+	$t_available_statuses = MantisEnum::getValues( config_get( 'status_enum_string' ) );
 
 	if( 'simple' == $t_filter['_view_type'] ) {
 
diff --git a/core/graph_api.php b/core/graph_api.php
index dc54107..d2e518b 100644
--- a/core/graph_api.php
+++ b/core/graph_api.php
@@ -421,21 +421,17 @@ function create_bug_enum_summary( $p_enum_string, $p_enum ) {
 	$t_user_id = auth_get_current_user_id();
 	$specific_where = " AND " . helper_project_specific_where( $t_project_id, $t_user_id );
 
-	$t_arr = explode_enum_string( $p_enum_string );
-	$enum_count = count( $t_arr );
-	for( $i = 0;$i < $enum_count;$i++ ) {
-		$t_s = explode_enum_arr( $t_arr[$i] );
-		$c_s[0] = addslashes( $t_s[0] );
-		$t_key = get_enum_to_string( $p_enum_string, $t_s[0] );
+	$t_metrics = array();
+	$t_assoc_array = MantisEnum::getAssocArrayIndexedByValues( $p_enum_string );
 
+	foreach ( $t_assoc_array as $t_value => $t_label  ) {
 		$query = "SELECT COUNT(*)
 					FROM $t_bug_table
-					WHERE $p_enum='$c_s[0]' $specific_where";
+					WHERE $p_enum='$t_value' $specific_where";
 		$result = db_query( $query );
-		$t_metrics[$t_key] = db_result( $result, 0 );
+		$t_metrics[$t_label] = db_result( $result, 0 );
 	}
 
-	# end for
 	return $t_metrics;
 }
 
@@ -450,36 +446,33 @@ function enum_bug_group( $p_enum_string, $p_enum ) {
 	$t_clo_val = CLOSED;
 	$specific_where = " AND " . helper_project_specific_where( $t_project_id, $t_user_id );
 
-	$t_arr = explode_enum_string( $p_enum_string );
-	$enum_count = count( $t_arr );
-	for( $i = 0;$i < $enum_count;$i++ ) {
-		$t_s = explode( ':', $t_arr[$i] );
-		$t_key = get_enum_to_string( $p_enum_string, $t_s[0] );
-
+	$t_array_indexed_by_enum_values = MantisEnum::getAssocArrayIndexedByValues( $p_enum_string );
+	$enum_count = count( $t_array_indexed_by_enum_values );
+	foreach ( $t_array_indexed_by_enum_values as $t_value => $t_label ) {
 		# Calculates the number of bugs opened and puts the results in a table
 		$query = "SELECT COUNT(*)
 					FROM $t_bug_table
-					WHERE $p_enum='$t_s[0]' AND
+					WHERE $p_enum='$t_value' AND
 						status<'$t_res_val' $specific_where";
 		$result2 = db_query( $query );
-		$t_metrics['open'][$t_key] = db_result( $result2, 0, 0 );
+		$t_metrics['open'][$t_label] = db_result( $result2, 0, 0 );
 
 		# Calculates the number of bugs closed and puts the results in a table
 		$query = "SELECT COUNT(*)
 					FROM $t_bug_table
-					WHERE $p_enum='$t_s[0]' AND
+					WHERE $p_enum='$t_value' AND
 						status='$t_clo_val' $specific_where";
 		$result2 = db_query( $query );
-		$t_metrics['closed'][$t_key] = db_result( $result2, 0, 0 );
+		$t_metrics['closed'][$t_label] = db_result( $result2, 0, 0 );
 
 		# Calculates the number of bugs resolved and puts the results in a table
 		$query = "SELECT COUNT(*)
 					FROM $t_bug_table
-					WHERE $p_enum='$t_s[0]' AND
+					WHERE $p_enum='$t_value' AND
 						status>='$t_res_val'  AND
 						status<'$t_clo_val' $specific_where";
 		$result2 = db_query( $query );
-		$t_metrics['resolved'][$t_key] = db_result( $result2, 0, 0 );
+		$t_metrics['resolved'][$t_label] = db_result( $result2, 0, 0 );
 	}
 
 	# ## end for
diff --git a/core/helper_api.php b/core/helper_api.php
index dcd8176..7816a79 100644
--- a/core/helper_api.php
+++ b/core/helper_api.php
@@ -60,30 +60,12 @@ function helper_alternate_class( $p_index = null, $p_odd_class = "row-1", $p_eve
 # --------------------
 # get the color string for the given status
 function get_status_color( $p_status ) {
-	$t_status_enum_string = config_get( 'status_enum_string' );
+	$t_status_label = MantisEnum::getLabel( config_get( 'status_enum_string' ), $p_status );
 	$t_status_colors = config_get( 'status_colors' );
-
-	# This code creates the appropriate variable name
-	# then references that color variable
-	# You could replace this with a bunch of if... then... else
-	# statements
-
-	$t_color_str = 'closed';
 	$t_color = '#ffffff';
-	$t_arr = explode_enum_string( $t_status_enum_string );
-	$t_arr_count = count( $t_arr );
-	for( $i = 0;$i < $t_arr_count;$i++ ) {
-		$elem_arr = explode_enum_arr( $t_arr[$i] );
-		if( $elem_arr[0] == $p_status ) {
-
-			# now get the appropriate translation
-			$t_color_str = $elem_arr[1];
-			break;
-		}
-	}
 
-	if( isset( $t_status_colors[$t_color_str] ) ) {
-		$t_color = $t_status_colors[$t_color_str];
+	if ( isset( $t_status_colors[$t_status_label] ) ) {
+		$t_color = $t_status_colors[$t_status_label];
 	}
 
 	return $t_color;
@@ -94,19 +76,8 @@ function get_status_color( $p_status ) {
 function get_enum_element( $p_enum_name, $p_val ) {
 	$config_var = config_get( $p_enum_name . '_enum_string' );
 	$string_var = lang_get( $p_enum_name . '_enum_string' );
-
-	# use the global enum string to search
-	$t_arr = explode_enum_string( $config_var );
-	$t_arr_count = count( $t_arr );
-	for( $i = 0;$i < $t_arr_count;$i++ ) {
-		$elem_arr = explode_enum_arr( $t_arr[$i] );
-		if( $elem_arr[0] == $p_val ) {
-
-			# now get the appropriate translation
-			return get_enum_to_string( $string_var, $p_val );
-		}
-	}
-	return '@' . $p_val . '@';
+	
+	return MantisEnum::getLocalizedLabel( $config_var, $string_var, $p_val );
 }
 
 # --------------------
diff --git a/core/html_api.php b/core/html_api.php
index 40a3bee..e3ecd95 100644
--- a/core/html_api.php
+++ b/core/html_api.php
@@ -980,9 +980,8 @@ function html_status_legend() {
 	echo '<table class="width100" cellspacing="1">';
 	echo '<tr>';
 
-	$t_status_array = get_enum_to_array( config_get( 'status_enum_string' ) );
-
-	$t_status_names = get_enum_to_array( lang_get( 'status_enum_string' ) );
+	$t_status_array = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) );
+	$t_status_names = MantisEnum::getAssocArrayIndexedByValues( lang_get( 'status_enum_string' ) );
 	$enum_count = count( $t_status_array );
 
 	# read through the list and eliminate unused ones for the selected project
@@ -1040,8 +1039,8 @@ function html_status_percentage_legend() {
 		$t_bug_count += $row['number'];
 	}
 
-	$t_arr = explode_enum_string( config_get( 'status_enum_string' ) );
-	$enum_count = count( $t_arr );
+	$t_enum_values = MantisEnum::getValues( config_get( 'status_enum_string' ) );
+	$enum_count = count( $t_enum_values );
 
 	if( $t_bug_count > 0 ) {
 		echo '<br />';
@@ -1051,12 +1050,10 @@ function html_status_percentage_legend() {
 		echo '</tr>';
 		echo '<tr>';
 
-		for( $i = 0;$i < $enum_count;$i++ ) {
-			$t_s = explode_enum_arr( $t_arr[$i] );
-			$t_color = get_status_color( $t_s[0] );
-			$t_status = $t_s[0];
+		foreach ( $t_enum_values as $t_status ) {
+			$t_color = get_status_color( $t_status );
 
-			if( !isset( $t_status_count_array[$t_status] ) ) {
+			if ( !isset( $t_status_count_array[$t_status] ) ) {
 				$t_status_count_array[$t_status] = 0;
 			}
 
diff --git a/core/print_api.php b/core/print_api.php
index 43ae435..ec2bb81 100644
--- a/core/print_api.php
+++ b/core/print_api.php
@@ -846,19 +846,16 @@ function print_build_option_list( $p_build = '' ) {
 function print_enum_string_option_list( $p_enum_name, $p_val = 0 ) {
 	$t_config_var_name = $p_enum_name . '_enum_string';
 	$t_config_var_value = config_get( $t_config_var_name );
+	
+	$t_enum_values = MantisEnum::getValues( $t_config_var_value );
 
-	$t_arr = explode_enum_string( $t_config_var_value );
-	$t_enum_count = count( $t_arr );
-	for( $i = 0;$i < $t_enum_count;$i++ ) {
-		$t_elem = explode_enum_arr( $t_arr[$i] );
-		$t_key = trim( $t_elem[0] );
+	foreach ( $t_enum_values as $t_key ) {
 		$t_elem2 = get_enum_element( $p_enum_name, $t_key );
+
 		echo "<option value=\"$t_key\"";
 		check_selected( $p_val, $t_key );
 		echo ">$t_elem2</option>";
 	}
-
-	# end for
 }
 
 # Select the proper enum values for status based on workflow
@@ -871,36 +868,34 @@ function get_status_option_list( $p_user_auth = 0, $p_current_value = 0, $p_show
 
 	if( count( $t_enum_workflow ) < 1 ) {
 		# workflow not defined, use default enum
-		$t_arr = explode_enum_string( $t_config_var_value );
+		$t_enum_values = MantisEnum::getValues( $t_config_var_value );
 	} else {
 		# workflow defined - find allowed states
 		if( isset( $t_enum_workflow[$p_current_value] ) ) {
-			$t_arr = explode_enum_string( $t_enum_workflow[$p_current_value] );
+			$t_enum_values = MantisEnum::getValues( $t_enum_workflow[$p_current_value] );
 		} else {
 			# workflow was not set for this status, this shouldn't happen
-			$t_arr = explode_enum_string( $t_config_var_value );
+			$t_enum_values = MantisEnum::getValues( $t_config_var_value );
 		}
 	}
 
-	$t_enum_count = count( $t_arr );
 	$t_enum_list = array();
 
-	for( $i = 0;$i < $t_enum_count;$i++ ) {
-		$t_elem = explode_enum_arr( $t_arr[$i] );
-		if( ( access_compare_level( $p_user_auth, access_get_status_threshold( $t_elem[0] ) ) ) 
-				&& ( !(( false == $p_show_current ) && ( $p_current_value == $t_elem[0] ) ) ) ) {
-			$t_enum_list[$t_elem[0]] = get_enum_element( 'status', $t_elem[0] );
+	foreach ( $t_enum_values as $t_enum_value ) {
+		if ( ( access_compare_level( $p_user_auth, access_get_status_threshold( $t_enum_value ) ) ) 
+				&& ( !(( false == $p_show_current ) && ( $p_current_value == $t_enum_value ) ) ) ) {
+			$t_enum_list[$t_enum_value] = get_enum_element( 'status', $t_enum_value );
 		}
 	}
 
-	# end for
-	if( true == $p_show_current ) {
+	if ( $p_show_current ) {
 		$t_enum_list[$p_current_value] = get_enum_element( 'status', $p_current_value );
 	}
-	if(( true == $p_add_close ) && 
-			( access_compare_level( $p_current_value, config_get( 'bug_resolved_status_threshold' ) ) ) ) {
+
+	if ( $p_add_close && access_compare_level( $p_current_value, config_get( 'bug_resolved_status_threshold' ) ) ) {
 		$t_enum_list[CLOSED] = get_enum_element( 'status', CLOSED );
 	}
+
 	return $t_enum_list;
 }
 
@@ -923,7 +918,7 @@ function print_status_option_list( $p_select_label, $p_current_value = 0, $p_all
 		}
 		echo '</select>';
 	} else {
-		echo get_enum_to_string( 'status_enum_string', $p_current_value );
+		echo MantisEnum::getLabel( 'status_enum_string', $p_current_value );
 	}
 }
 
@@ -945,19 +940,18 @@ function print_project_access_levels_option_list( $p_val, $p_project_id = null )
 	echo "<option value=\"" . DEFAULT_ACCESS_LEVEL . "\"";
 	echo ">[" . lang_get( 'default_access_level' ) . "]</option>";
 
-	$t_arr = explode_enum_string( $t_access_levels_enum_string );
-	$enum_count = count( $t_arr );
-	for( $i = 0;$i < $enum_count;$i++ ) {
-		$t_elem = explode_enum_arr( $t_arr[$i] );
+	$t_enum_values = MantisEnum::getValues( $t_access_levels_enum_string );
 
+	foreach ( $t_enum_values as $t_enum_value ) {
 		# a user must not be able to assign another user an access level that is higher than theirs.
-		if( $t_elem[0] > $t_current_user_access_level ) {
+		if ( $t_enum_value > $t_current_user_access_level ) {
 			continue;
 		}
 
-		$t_access_level = get_enum_element( 'access_levels', $t_elem[0] );
-		echo "<option value=\"$t_elem[0]\"";
-		check_selected( $p_val, $t_elem[0] );
+		$t_access_level = get_enum_element( 'access_levels', $t_enum_value );
+
+		echo "<option value=\"$t_enum_value\"";
+		check_selected( $p_val, $t_enum_value );
 		echo ">$t_access_level</option>";
 	}
 
diff --git a/core/summary_api.php b/core/summary_api.php
index 9e14721..8116fd2 100644
--- a/core/summary_api.php
+++ b/core/summary_api.php
@@ -51,8 +51,6 @@ function summary_print_by_enum( $p_enum_string, $p_enum ) {
 	}
 
 	$t_filter_prefix = config_get( 'bug_count_hyperlink_prefix' );
-	$t_arr = explode_enum_string( $p_enum_string );
-	$enum_count = count( $t_arr );
 
 	$t_mantis_bug_table = db_get_table( 'mantis_bug_table' );
 	$t_status_query = ( 'status' == $p_enum ) ? '' : ' ,status ';
@@ -764,14 +762,9 @@ function summary_print_developer_resolution( $p_resolution_enum_string ) {
 	$t_project_id = helper_get_current_project();
 	$t_user_id = auth_get_current_user_id();
 
-	# Organise an array of resolution values to be used later
-	$t_res_arr = explode_enum_string( $p_resolution_enum_string );
-	$enum_res_count = count( $t_res_arr );
-	$c_res_s = array();
-	for( $i = 0;$i < $enum_res_count;$i++ ) {
-		$t_res_s = explode_enum_arr( $t_res_arr[$i] );
-		$c_res_s[$i] = db_prepare_string( $t_res_s[0] );
-	}
+	# Get the resolution values ot use
+	$c_res_s = MantisEnum::getValues( $p_resolution_enum_string );
+	$enum_res_count = count( $c_res_s );
 
 	$specific_where = helper_project_specific_where( $t_project_id );
 	if( ' 1<>1' == $specific_where ) {
@@ -874,14 +867,9 @@ function summary_print_reporter_resolution( $p_resolution_enum_string ) {
 	$t_project_id = helper_get_current_project();
 	$t_user_id = auth_get_current_user_id();
 
-	# Organise an array of resolution values to be used later
-	$t_res_arr = explode_enum_string( $p_resolution_enum_string );
-	$enum_res_count = count( $t_res_arr );
-	$c_res_s = array();
-	for( $i = 0;$i < $enum_res_count;$i++ ) {
-		$t_res_s = explode_enum_arr( $t_res_arr[$i] );
-		$c_res_s[$i] = db_prepare_string( $t_res_s[0] );
-	}
+	# Get the resolution values ot use
+	$c_res_s = MantisEnum::getValues( $p_resolution_enum_string );
+	$enum_res_count = count( $c_res_s );
 
 	# Checking if it's a per project statistic or all projects
 	$specific_where = helper_project_specific_where( $t_project_id );
@@ -1006,21 +994,13 @@ function summary_print_reporter_effectiveness( $p_severity_enum_string, $p_resol
 	$t_notbug_multiplier[DUPLICATE] = 3;
 	$t_notbug_multiplier[NOT_A_BUG] = 5;
 
-	$t_sev_arr = explode_enum_string( $p_severity_enum_string );
-	$enum_sev_count = count( $t_sev_arr );
-	$c_sev_s = array();
-	for( $i = 0;$i < $enum_sev_count;$i++ ) {
-		$t_sev_s = explode_enum_arr( $t_sev_arr[$i] );
-		$c_sev_s[$i] = db_prepare_string( $t_sev_s[0] );
-	}
+	# Get the severity values ot use
+	$c_sev_s = MantisEnum::getValues( $p_severity_enum_string );
+	$enum_sev_count = count( $c_sev_s );
 
-	$t_res_arr = explode_enum_string( $p_resolution_enum_string );
-	$enum_res_count = count( $t_res_arr );
-	$c_res_s = array();
-	for( $i = 0;$i < $enum_res_count;$i++ ) {
-		$t_res_s = explode_enum_arr( $t_res_arr[$i] );
-		$c_res_s[$i] = db_prepare_string( $t_res_s[0] );
-	}
+	# Get the resolution values ot use
+	$c_res_s = MantisEnum::getValues( $p_resolution_enum_string );
+	$enum_res_count = count( $c_res_s );
 
 	# Checking if it's a per project statistic or all projects
 	$specific_where = helper_project_specific_where( $t_project_id );
diff --git a/core/utility_api.php b/core/utility_api.php
index c86d6d1..d7961cf 100644
--- a/core/utility_api.php
+++ b/core/utility_api.php
@@ -46,63 +46,6 @@ function trans_bool( $p_num ) {
 }
 
 /**
- * Breaks up an enum string into num:value elements
- * @param string $p_enum_string enum string
- * @return array array of num:value elements
- * @access public
- */
-function explode_enum_string( $p_enum_string ) {
-	return explode( ',', $p_enum_string );
-}
-
-/**
- * Given one num:value pair it will return both in an array
- * num will be first (element 0) value second (element 1)
- * @param string $p_enum_elem a num:value pair
- * @return array array(num->value)
- * @access public
- */
-function explode_enum_arr( $p_enum_elem ) {
-	return explode( ':', $p_enum_elem );
-}
-
-/**
- * Get the string associated with the $p_enum value
- * @param string $p_enum_string
- * @return array
- * @access public
- */
-function get_enum_to_array( $p_enum_string ) {
-	$t_arr = explode_enum_string( $p_enum_string );
-	$enum_count = count( $t_arr );
-	for( $i = 0;$i < $enum_count;$i++ ) {
-		$t_s = explode_enum_arr( $t_arr[$i] );
-		$t_index = (int) $t_s[0];
-		$t_array[$t_index] = $t_s[1];
-	}
-	return $t_array;
-}
-
-/**
- * Get the string associated with the $p_enum value
- * @param string $p_enum_string
- * @param int $p_num
- * @return string
- * @access public
- */
-function get_enum_to_string( $p_enum_string, $p_num ) {
-	$t_arr = explode_enum_string( $p_enum_string );
-	$enum_count = count( $t_arr );
-	for( $i = 0;$i < $enum_count;$i++ ) {
-		$t_s = explode_enum_arr( $t_arr[$i] );
-		if( $t_s[0] == $p_num ) {
-			return $t_s[1];
-		}
-	}
-	return '@' . $p_num . '@';
-}
-
-/**
  * Add a trailing DIRECTORY_SEPARATOR to a string if it isn't present
  * @param string $p_path
  * @return string
diff --git a/excel_xml_export.php b/excel_xml_export.php
index ba04ec4..c5a0d07 100644
--- a/excel_xml_export.php
+++ b/excel_xml_export.php
@@ -67,7 +67,7 @@
 	echo excel_get_header( $t_export_title );
 	echo excel_get_titles_row();
 
-	$f_bug_arr = explode_enum_string( $f_export );
+	$f_bug_arr = explode( ',', $f_export );
 
 	$t_columns = excel_get_columns();
 
diff --git a/manage_config_email_page.php b/manage_config_email_page.php
index cafb9c9..b0f166a 100644
--- a/manage_config_email_page.php
+++ b/manage_config_email_page.php
@@ -140,7 +140,7 @@
 
 	function get_section_begin_for_email( $p_section_name ) {
 		global $t_project;
-		$t_access_levels = explode_enum_string( config_get( 'access_levels_enum_string' ) );
+		$t_access_levels = MantisEnum::getValues( config_get( 'access_levels_enum_string' ) );
 		echo '<table class="width100">';
 		echo '<tr><td class="form-title" colspan="' . ( count( $t_access_levels ) + 7 ) . '">' . $p_section_name . '</td></tr>' . "\n";
 		echo '<tr><td class="form-title" width="30%" rowspan="2">' . lang_get( 'message' ) . '</td>';
@@ -149,15 +149,16 @@
 		echo '<td class="form-title" style="text-align:center" rowspan="2">&nbsp;' . lang_get( 'users_monitoring_bug' ) . '&nbsp;</td>';
 		echo '<td class="form-title" style="text-align:center" rowspan="2">&nbsp;' . lang_get( 'users_added_bugnote' ) . '&nbsp;</td>';
 		echo '<td class="form-title" style="text-align:center" colspan="' . count( $t_access_levels ) . '">&nbsp;' . lang_get( 'access_levels' ) . '&nbsp;</td></tr><tr>';
+
 		foreach( $t_access_levels as $t_access_level ) {
-			$t_entry_array = explode_enum_arr( $t_access_level );
-			echo '<td class="form-title" style="text-align:center">&nbsp;' . get_enum_to_string( lang_get( 'access_levels_enum_string' ), $t_entry_array[0] ) . '&nbsp;</td>';
+			echo '<td class="form-title" style="text-align:center">&nbsp;' . MantisEnum::getLabel( lang_get( 'access_levels_enum_string' ), $t_access_level ) . '&nbsp;</td>';
 		}
+
 		echo '</tr>' . "\n";
 	}
 
 	function get_capability_row_for_email( $p_caption, $p_message_type ) {
-		$t_access_levels = explode_enum_string( config_get( 'access_levels_enum_string' ) );
+		$t_access_levels = ManisEnum::getValues( config_get( 'access_levels_enum_string' ) );
 
 		echo '<tr ' . helper_alternate_class() . '><td>' . string_display( $p_caption ) . '</td>';
 		echo '<td class="center"' . colour_notify_flag( $p_message_type, 'reporter' ) . '>' . show_notify_flag( $p_message_type, 'reporter' )  . '</td>';
@@ -166,9 +167,9 @@
 		echo '<td class="center"' . colour_notify_flag( $p_message_type, 'bugnotes' ) . '>' . show_notify_flag( $p_message_type, 'bugnotes' ) . '</td>';
 
 		foreach( $t_access_levels as $t_access_level ) {
-			$t_entry_array = explode_enum_arr( $t_access_level );
-			echo '<td class="center"' . colour_threshold_flag( (int)$t_entry_array[0], $p_message_type ) . '>' . show_notify_threshold( (int)$t_entry_array[0], $p_message_type ) . '</td>';
+			echo '<td class="center"' . colour_threshold_flag( $t_access_level, $p_message_type ) . '>' . show_notify_threshold( $t_access_level, $p_message_type ) . '</td>';
 		}
+
 		echo '</tr>' . "\n";
 	}
 
@@ -197,7 +198,7 @@
 
 	$t_actions[] = 'relationship';
 
-	$t_statuses = get_enum_to_array( config_get( 'status_enum_string' ) );
+	$t_statuses = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) );
 	foreach( $t_statuses as $t_status ) {
 		$t_actions[] =  $t_status;
 	}
@@ -267,10 +268,9 @@
 
 		get_capability_row_for_email( lang_get( 'email_on_relationship_changed' ), 'relationship' );
 
-		$t_statuses = explode_enum_string( config_get( 'status_enum_string' ) );
-		foreach( $t_statuses as $t_status ) {
-			list( $t_state, $t_label ) = explode_enum_arr( $t_status );
-			get_capability_row_for_email( lang_get( 'status_changed_to' ) . ' \'' . get_enum_element( 'status', $t_state ) . '\'', $t_label );
+		$t_statuses = MantisEnum::getValues( config_get( 'status_enum_string' ) );
+		foreach ( $t_statuses as $t_status ) {
+			get_capability_row_for_email( lang_get( 'status_changed_to' ) . ' \'' . get_enum_element( 'status', $t_status ) . '\'', $t_label );
 		}
 
 		get_section_end_for_email();
diff --git a/manage_config_email_set.php b/manage_config_email_set.php
index b464203..6817688 100644
--- a/manage_config_email_set.php
+++ b/manage_config_email_set.php
@@ -58,7 +58,7 @@
 
 	$t_valid_actions[] = 'relationship';
 
-	$t_statuses = get_enum_to_array( config_get( 'status_enum_string' ) );
+	$t_statuses = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) );
     ksort( $t_statuses );
     reset( $t_statuses );
 
diff --git a/manage_config_work_threshold_page.php b/manage_config_work_threshold_page.php
index 0e17ca3..67379de 100644
--- a/manage_config_work_threshold_page.php
+++ b/manage_config_work_threshold_page.php
@@ -41,7 +41,7 @@
 	$t_access = user_get_access_level( $t_user, $t_project_id );
 	$t_show_submit = false;
 
-	$t_access_levels = get_enum_to_array( config_get( 'access_levels_enum_string' ) );
+	$t_access_levels = MantisEnum::getAssocArrayIndexedByValues( config_get( 'access_levels_enum_string' ) );
 
 	$t_overrides = array();	
 	function set_overrides( $p_config ) {
@@ -60,7 +60,7 @@
 		echo '<td class="form-title"style="text-align:center"  width="40%" colspan="' . count( $t_access_levels ) . '">' . lang_get( 'access_levels' ) . '</td>';
 		echo '<td class="form-title" style="text-align:center" rowspan="2">&nbsp;' . lang_get( 'alter_level' ) . '&nbsp;</td></tr><tr>';
 		foreach( $t_access_levels as $t_access_level => $t_access_label ) {
-			echo '<td class="form-title" style="text-align:center">&nbsp;' . get_enum_to_string( lang_get( 'access_levels_enum_string' ), $t_access_level ) . '&nbsp;</td>';
+			echo '<td class="form-title" style="text-align:center">&nbsp;' . MantisEnum::getLabel( lang_get( 'access_levels_enum_string' ), $t_access_level ) . '&nbsp;</td>';
 		}
 		echo '</tr>' . "\n";
 	}
@@ -145,7 +145,7 @@
 			print_enum_string_option_list( 'access_levels', config_get_access( $p_threshold ) );
 			echo '</select> </td>';
 		} else {
-			echo '<td>' . get_enum_to_string( lang_get( 'access_levels_enum_string' ), config_get_access( $p_threshold ) ) . '&nbsp;</td>';
+			echo '<td>' . MantisEnum::getLabel( lang_get( 'access_levels_enum_string' ), config_get_access( $p_threshold ) ) . '&nbsp;</td>';
 		}
 
 		echo '</tr>' . "\n";
@@ -194,7 +194,7 @@
 			print_enum_string_option_list( 'access_levels', config_get_access( $p_threshold ) );
 			echo '</select> </td>';
 		} else {
-			echo '<td>' . get_enum_to_string( lang_get( 'access_levels_enum_string' ), config_get_access( $p_threshold ) ) . '&nbsp;</td>';
+			echo '<td>' . MantisEnum::getLabel( lang_get( 'access_levels_enum_string' ), config_get_access( $p_threshold ) ) . '&nbsp;</td>';
 		}
 
 		echo '</tr>' . "\n";
@@ -231,7 +231,7 @@
 			echo '</select></td><td colspan="' . ( count( $t_access_levels ) - 3 ) . '"></td>';
 		    $t_show_submit = true;
 		} else {
-			$t_value = get_enum_to_string( lang_get( $p_enum . '_enum_string' ), config_get( $p_threshold ) ) . '&nbsp;';
+			$t_value = MantisEnum::getLabel( lang_get( $p_enum . '_enum_string' ), config_get( $p_threshold ) ) . '&nbsp;';
 		    echo '<td class="left" colspan="3"' . $t_colour . '>' . $t_value . '</td><td colspan="' . ( count( $t_access_levels ) - 3 ) . '"></td>';
         }
 
@@ -240,7 +240,7 @@
 			print_enum_string_option_list( 'access_levels', config_get_access( $p_threshold ) );
 			echo '</select> </td>';
 		} else {
-			echo '<td>' . get_enum_to_string( lang_get( 'access_levels_enum_string' ), config_get_access( $p_threshold ) ) . '&nbsp;</td>';
+			echo '<td>' . MantisEnum::getLabel( lang_get( 'access_levels_enum_string' ), config_get_access( $p_threshold ) ) . '&nbsp;</td>';
 		}
 
 		echo '</tr>' . "\n";
diff --git a/manage_config_work_threshold_set.php b/manage_config_work_threshold_set.php
index 4fa64a6..fe7980c 100644
--- a/manage_config_work_threshold_set.php
+++ b/manage_config_work_threshold_set.php
@@ -49,7 +49,7 @@
 	        $f_threshold = gpc_get_int_array( 'flag_thres_' . $p_threshold, array() );
 	        $f_access = gpc_get_int( 'access_' . $p_threshold );
             # @@debug @@ echo "<br />for $p_threshold "; var_dump($f_threshold, $f_access); echo '<br />';
-		    $t_access_levels = get_enum_to_array( config_get( 'access_levels_enum_string' ) );
+		    $t_access_levels = MantisEnum::getAssocArrayIndexedByValues( config_get( 'access_levels_enum_string' ) );
 		    ksort( $t_access_levels );
 		    reset( $t_access_levels );
 
diff --git a/manage_config_workflow_page.php b/manage_config_workflow_page.php
index 2cbbb7c..b2129fd 100644
--- a/manage_config_workflow_page.php
+++ b/manage_config_workflow_page.php
@@ -50,7 +50,7 @@
 	}
 
 	function parse_workflow( $p_enum_workflow ) {
-        $t_status_arr  = get_enum_to_array( config_get( 'status_enum_string' ) );
+        $t_status_arr  = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) );
         if ( 0 == count( $p_enum_workflow ) ) {
             # workflow is not set, default it to all transitions
 	        foreach ( $t_status_arr as $t_status => $t_label ) {
@@ -69,7 +69,7 @@
 
     	# prepopulate new bug state (bugs go from nothing to here)
     	$t_submit_status_array = config_get( 'bug_submit_status' );
-    	$t_new_label = get_enum_to_string( lang_get( 'status_enum_string' ), NEW_ );
+    	$t_new_label = MantisEnum::getLabel( lang_get( 'status_enum_string' ), NEW_ );
     	if ( is_array( $t_submit_status_array ) ) {
     		# @@@ (thraxisp) this is not implemented in bug_api.php
     		foreach ($t_submit_status_array as $t_access => $t_status ) {
@@ -84,12 +84,12 @@
 
         # add user defined arcs and implicit reopen arcs
     	$t_reopen = config_get( 'bug_reopen_status' );
-    	$t_reopen_label = get_enum_to_string( lang_get( 'resolution_enum_string' ), REOPENED );
+    	$t_reopen_label = MantisEnum::getLabel( lang_get( 'resolution_enum_string' ), REOPENED );
     	$t_resolved_status = config_get( 'bug_resolved_status_threshold' );
     	$t_default = array();
     	foreach ( $t_status_arr as $t_status => $t_status_label ) {
     		if ( isset( $p_enum_workflow[$t_status] ) ) {
-    			$t_next_arr = get_enum_to_array( $p_enum_workflow[$t_status] );
+    			$t_next_arr = MantisEnum::getAssocArrayIndexedByValues( $p_enum_workflow[$t_status] );
     			foreach ( $t_next_arr as $t_next => $t_next_label) {
                     if ( ! isset( $t_default[$t_status] ) ) {
     	                $t_default[$t_status] = $t_next;
@@ -159,26 +159,27 @@
 	}
 
 	function section_begin( $p_section_name ) {
-		$t_enum_status = explode_enum_string( config_get( 'status_enum_string' ) );
+		$t_enum_statuses = MantisEnum::getValues( config_get( 'status_enum_string' ) );
 		echo '<table class="width100">';
-		echo '<tr><td class="form-title" colspan="' . ( count( $t_enum_status ) + 2 ) . '">'
+		echo '<tr><td class="form-title" colspan="' . ( count( $t_enum_statuses ) + 2 ) . '">'
 			. $p_section_name . '</td></tr>' . "\n";
 		echo '<tr><td class="form-title" width="30%" rowspan="2">' . lang_get( 'current_status' ) . '</td>';
-		echo '<td class="form-title" style="text-align:center" colspan="' . ( count( $t_enum_status ) + 1 ) . '">'
+		echo '<td class="form-title" style="text-align:center" colspan="' . ( count( $t_enum_statuses ) + 1 ) . '">'
 			. lang_get( 'next_status' ) . '</td></tr>';
 		echo "\n<tr>";
-		foreach( $t_enum_status as $t_status ) {
-			$t_entry_array = explode_enum_arr( $t_status );
-			echo '<td class="form-title" style="text-align:center">&nbsp;' . string_no_break( get_enum_to_string( lang_get( 'status_enum_string' ), $t_entry_array[0] ) ) . '&nbsp;</td>';
+
+		foreach( $t_enum_statuses as $t_status ) {
+			echo '<td class="form-title" style="text-align:center">&nbsp;' . string_no_break( MantisEnum::getLabel( lang_get( 'status_enum_string' ), $t_status ) ) . '&nbsp;</td>';
 		}
-			echo '<td class="form-title" style="text-align:center">' . lang_get( 'custom_field_default_value' ) . '</td>';
+
+		echo '<td class="form-title" style="text-align:center">' . lang_get( 'custom_field_default_value' ) . '</td>';
 		echo '</tr>' . "\n";
 	}
 
 	function capability_row( $p_from_status ) {
 		global $t_file_workflow, $t_global_workflow, $t_project_workflow, $t_colour_global, $t_colour_project, $t_can_change_workflow;
-		$t_enum_status = get_enum_to_array( config_get( 'status_enum_string' ) );
-		echo '<tr ' . helper_alternate_class() . '><td>' . string_no_break( get_enum_to_string( lang_get( 'status_enum_string' ), $p_from_status ) ) . '</td>';
+		$t_enum_status = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) );
+		echo '<tr ' . helper_alternate_class() . '><td>' . string_no_break( MantisEnum::getLabel( lang_get( 'status_enum_string' ), $p_from_status ) ) . '</td>';
 		foreach ( $t_enum_status as $t_to_status_id => $t_to_status_label ) {
 			echo show_flag( $p_from_status, $t_to_status_id );
 		}
@@ -206,7 +207,7 @@
             print_enum_string_option_list( 'status', $t_project );
             echo '</select>';
         } else {
-            echo get_enum_to_string( lang_get( 'status_enum_string' ), $t_project );
+            echo MantisEnum::getLabel( lang_get( 'status_enum_string' ), $t_project );
         }
         echo ' </td>';
 		echo '</tr>' . "\n";
@@ -256,8 +257,8 @@
 			echo '</select> </td>';
 			$t_can_change_flags = true;
 		} else {
-			echo '<td' . $t_colour . '>' . get_enum_to_string( lang_get( 'status_enum_string' ), $t_project ) . '&nbsp;</td>';
-			echo '<td>' . get_enum_to_string( lang_get( 'access_levels_enum_string' ), config_get_access( $p_threshold ) ) . '&nbsp;</td>';
+			echo '<td' . $t_colour . '>' . MantisEnum::getLabel( lang_get( 'status_enum_string' ), $t_project ) . '&nbsp;</td>';
+			echo '<td>' . MantisEnum::getLabel( lang_get( 'access_levels_enum_string' ), config_get_access( $p_threshold ) ) . '&nbsp;</td>';
 		}
 
 		echo '</tr>' . "\n";
@@ -268,7 +269,6 @@
 	}
 
 	function access_begin( $p_section_name ) {
-		$t_enum_status = explode_enum_string( config_get( 'status_enum_string' ) );
 		echo '<table class="width100">';
 		echo '<tr><td class="form-title" colspan="2">'
 			. $p_section_name . '</td></tr>' . "\n";
@@ -278,7 +278,7 @@
 	function access_row() {
 		global $t_access, $t_can_change_flags, $t_colour_project, $t_colour_global;
 
-		$t_enum_status = get_enum_to_array( config_get( 'status_enum_string' ) );
+		$t_enum_status = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) );
 
 		$t_file_new = config_get_global( 'report_bug_threshold' );
 		$t_global_new = config_get( 'report_bug_threshold', null, null, ALL_PROJECTS );
@@ -306,7 +306,7 @@
 		}
 
 		foreach ( $t_enum_status as $t_status => $t_status_label) {
-			echo '<tr ' . helper_alternate_class() . '><td width="30%">' . string_no_break( get_enum_to_string( lang_get( 'status_enum_string' ), $t_status ) ) . '</td>';
+			echo '<tr ' . helper_alternate_class() . '><td width="30%">' . string_no_break( MantisEnum::getLabel( lang_get( 'status_enum_string' ), $t_status ) ) . '</td>';
 			if ( NEW_ == $t_status ) {
 				$t_level = $t_project_new;
 				$t_can_change = ( $t_access >= config_get_access( 'report_bug_threshold' ) );
@@ -348,7 +348,7 @@
 				echo '</select> </td>';
 			    $t_can_change_flags = true;
 			} else {
-				echo '<td class="center"' . $t_colour . '>' . get_enum_to_string( lang_get( 'access_levels_enum_string' ), $t_level ) . '</td>';
+				echo '<td class="center"' . $t_colour . '>' . MantisEnum::getLabel( lang_get( 'access_levels_enum_string' ), $t_level ) . '</td>';
 			}
 			echo '</tr>' . "\n";
 		}
@@ -358,7 +358,7 @@
 
 	# count arcs in and out of each status
 	$t_enum_status = config_get( 'status_enum_string' );
-	$t_status_arr  = get_enum_to_array( $t_enum_status );
+	$t_status_arr  = MantisEnum::getAssocArrayIndexedByValues( $t_enum_status );
 
 	$t_extra_enum_status = '0:non-existent,' . $t_enum_status;
 	$t_lang_enum_status = '0:' . lang_get( 'non_existent' ) . ',' . lang_get( 'status_enum_string' );
@@ -374,7 +374,7 @@
 	foreach ( $t_status_arr as $t_status => $t_label ) {
 		if ( isset( $t_project_workflow['exit'][$t_status][$t_status] ) ) {
 			$t_validation_result .= '<tr ' . helper_alternate_class() . '><td>'
-							. get_enum_to_string( $t_lang_enum_status, $t_status )
+							. MantisEnum::getLabel( $t_lang_enum_status, $t_status )
 							. '</td><td bgcolor="#FFED4F">' . lang_get( 'superfluous' ) . '</td>';
 		}
 	}
@@ -383,7 +383,7 @@
 	foreach ( $t_status_arr as $t_status => $t_status_label) {
 		if ( ( 0 == count( $t_project_workflow['entry'][$t_status] ) ) && ( 0 < count( $t_project_workflow['exit'][$t_status] ) ) ){
 			$t_validation_result .= '<tr ' . helper_alternate_class() . '><td>'
-							. get_enum_to_string( $t_lang_enum_status, $t_status )
+							. MantisEnum::getLabel( $t_lang_enum_status, $t_status )
 							. '</td><td bgcolor="#FF0088">' . lang_get( 'unreachable' ) . '</td>';
 		}
 	}
@@ -392,7 +392,7 @@
 	foreach ( $t_status_arr as $t_status => $t_status_label ) {
 		if ( ( 0 == count( $t_project_workflow['exit'][$t_status] ) ) && ( 0 < count( $t_project_workflow['entry'][$t_status] ) ) ){
 			$t_validation_result .= '<tr ' . helper_alternate_class() . '><td>'
-							. get_enum_to_string( $t_lang_enum_status, $t_status )
+							. MantisEnum::getLabel( $t_lang_enum_status, $t_status )
 							. '</td><td bgcolor="#FF0088">' . lang_get( 'no_exit' ) . '</td>';
 		}
 	}
@@ -401,7 +401,7 @@
 	foreach ( $t_status_arr as $t_status => $t_status_label ) {
 		if ( ( 0 == count( $t_project_workflow['exit'][$t_status] ) ) && ( 0 == count( $t_project_workflow['entry'][$t_status] ) ) ){
 			$t_validation_result .= '<tr ' . helper_alternate_class() . '><td>'
-							. get_enum_to_string( $t_lang_enum_status, $t_status )
+							. MantisEnum::getLabel( $t_lang_enum_status, $t_status )
 							. '</td><td bgcolor="#FF0088">' . lang_get( 'unreachable' ) . '<br />' . lang_get( 'no_exit' ) . '</td>';
 		}
 	}
diff --git a/manage_config_workflow_set.php b/manage_config_workflow_set.php
index 56b1bc9..808a9a1 100644
--- a/manage_config_workflow_set.php
+++ b/manage_config_workflow_set.php
@@ -66,7 +66,7 @@
 			list( $t_from, $t_to ) = split( ':', $t_transition );
 			$t_matrix[$t_from][$t_to] = '';
 		}
-		$t_statuses = get_enum_to_array( config_get( 'status_enum_string' ) );
+		$t_statuses = MantisEnum::getAssocArrayIndexedByValues( config_get( 'status_enum_string' ) );
 		foreach( $t_statuses as $t_state => $t_label) {
 			$t_workflow_row = '';
 			$t_default = gpc_get_int( 'default_' . $t_state );
@@ -103,7 +103,7 @@
 		$f_access = gpc_get( 'status_access' );
 
 		# walk through the status labels to set the status threshold
-		$t_enum_status = explode_enum_string( config_get( 'status_enum_string' ) );
+		$t_enum_status = explode( ',', config_get( 'status_enum_string' ) );
 		$t_set_status = array();
 		foreach( $t_statuses as $t_status_id => $t_status_label) {
 			$f_level = gpc_get( 'access_change_' . $t_status_id );
diff --git a/print_all_bug_page_word.php b/print_all_bug_page_word.php
index 44f2f40..6e3a185 100644
--- a/print_all_bug_page_word.php
+++ b/print_all_bug_page_word.php
@@ -85,7 +85,7 @@ xmlns="http://www.w3.org/TR/REC-html40">
 <?php html_body_begin() ?>
 
 <?php
-	$f_bug_arr = explode_enum_string( $f_export );
+	$f_bug_arr = explode( ',', $f_export );
 	$t_count_exported = 0;
 
 	for( $j=0; $j < $t_row_count; $j++ ) {
diff --git a/summary_page.php b/summary_page.php
index c3d16b2..fb12d99 100644
--- a/summary_page.php
+++ b/summary_page.php
@@ -360,20 +360,13 @@
 				<?php echo lang_get( 'reporter_by_resolution' ) ?>
 			</td>
 			<?php
-			$t_arr = explode_enum_string( config_get( 'resolution_enum_string' ) );
-			$enum_count = count( $t_arr );
-
-			for ($i=0;$i<$enum_count;$i++) {
-				print '<td>';
-				$t_s = explode_enum_arr( $t_arr[$i] );
-				$c_s[0] = db_prepare_string( $t_s[0] );
-				echo get_enum_element( 'resolution', $c_s[0] );
-				print '</td>';
+			$t_resolutions = MantisEnum::getValues( config_get( 'resolution_enum_string' ) );
+
+			foreach ( $t_resolutions as $t_resolution ) {
+				echo '<td>', get_enum_element( 'resolution', $t_resolution ), '</td>';
 			}
 
-			print '<td>';
-			print lang_get( 'percentage_errors' );
-			print '</td>';
+			echo '<td>', lang_get( 'percentage_errors' ), '</td>';
 			?>
 		</tr>
 		<?php summary_print_reporter_resolution( config_get( 'resolution_enum_string' ) ) ?>
@@ -390,20 +383,13 @@
 				<?php echo lang_get( 'developer_by_resolution' ) ?>
 			</td>
 			<?php
-			$t_arr = explode_enum_string( config_get( 'resolution_enum_string' ) );
-			$enum_count = count( $t_arr );
-
-			for ($i=0;$i<$enum_count;$i++) {
-				print '<td>';
-				$t_s = explode_enum_arr( $t_arr[$i] );
-				$c_s[0] = db_prepare_string( $t_s[0] );
-				echo get_enum_element( 'resolution', $c_s[0] );
-				print '</td>';
+			$t_resolutions = MantisEnum::getValues( config_get( 'resolution_enum_string' ) );
+
+			foreach ( $t_resolutions as $t_resolution ) {
+				echo '<td>', get_enum_element( 'resolution', $t_resolution ), '</td>';
 			}
 
-			print '<td>';
-			print lang_get( 'percentage_fixed' );
-			print '</td>';
+			echo '<td>', lang_get( 'percentage_fixed' ), '</td>';
 			?>
 		</tr>
 		<?php summary_print_developer_resolution( config_get( 'resolution_enum_string' ) ) ?>
diff --git a/tests/MantisEnumTest.php b/tests/MantisEnumTest.php
new file mode 100644
index 0000000..43009cf
--- /dev/null
+++ b/tests/MantisEnumTest.php
@@ -0,0 +1,103 @@
+<?php
+/*
+ * Created on Dec 1, 2008
+ *
+ * To change the template for this generated file go to
+ * Window - Preferences - PHPeclipse - PHP - Code Templates
+ */
+
+require_once 'PHPUnit/Framework.php';
+
+$t_root_path = dirname( dirname( __FILE__ ) )  . DIRECTORY_SEPARATOR;
+require_once $t_root_path . 'core/classes/MantisEnum.class.php';
+
+/**
+ * Test cases for MantisEnum class.
+ */
+class MantisEnumTest extends PHPUnit_Framework_TestCase
+{
+	const ACCESS_LEVELS_ENUM = '10:viewer,25:reporter,40:updater,55:developer,70:manager,90:administrator';
+	const EMPTY_ENUM = '';
+	const DUPLICATE_VALUES_ENUM = '10:viewer1,10:viewer2';
+	const DUPLICATE_LABELS_ENUM = '10:viewer,20:viewer';
+	const SINGLE_VALUE_ENUM = '10:viewer';
+	const NAME_WITH_SPACES_ENUM = '10:first label,20:second label';
+	const NON_TRIMMED_ENUM = '10 : viewer, 20 : reporter';
+
+	/**
+	 * Standard tests against a valid enum.
+	 */
+    public function testGetStringFromValue()
+    {    	
+        $this->assertEquals( 'viewer', MantisEnum::getLabel( MantisEnumTest::ACCESS_LEVELS_ENUM, 10 ) );
+        $this->assertEquals( 'reporter', MantisEnum::getLabel( MantisEnumTest::ACCESS_LEVELS_ENUM, 25 ) );
+        $this->assertEquals( 'updater', MantisEnum::getLabel( MantisEnumTest::ACCESS_LEVELS_ENUM, 40 ) );
+        $this->assertEquals( 'developer', MantisEnum::getLabel( MantisEnumTest::ACCESS_LEVELS_ENUM, 55 ) );
+        $this->assertEquals( 'manager', MantisEnum::getLabel( MantisEnumTest::ACCESS_LEVELS_ENUM, 70 ) );
+        $this->assertEquals( 'administrator', MantisEnum::getLabel( MantisEnumTest::ACCESS_LEVELS_ENUM, 90 ) );
+        $this->assertEquals( '@100@', MantisEnum::getLabel( MantisEnumTest::ACCESS_LEVELS_ENUM, 100 ) );
+        $this->assertEquals( '@-1@', MantisEnum::getLabel( MantisEnumTest::ACCESS_LEVELS_ENUM, -1 ) );
+    }
+    
+    public function testGetValues()
+    {
+        $this->assertEquals( array( 10, 25, 40, 55, 70,90 ), MantisEnum::getValues( MantisEnumTest::ACCESS_LEVELS_ENUM, 10 ) );
+        $this->assertEquals( array(), MantisEnum::getValues( MantisEnumTest::EMPTY_ENUM, 10 ) );
+    }
+
+	/**
+	 * Tests against an empty enum
+	 */
+    public function testEmptyEnum()
+    {    	
+        $this->assertEquals( '@10@', MantisEnum::getLabel( MantisEnumTest::EMPTY_ENUM, 10 ) );
+    }
+
+	/**
+	 * Tests enumerations that contain duplicate values.
+	 */
+    public function testDuplicateValuesEnum()
+    {    	
+        $this->assertEquals( 'viewer1', MantisEnum::getLabel( MantisEnumTest::DUPLICATE_VALUES_ENUM, 10 ) );
+        $this->assertEquals( '@100@', MantisEnum::getLabel( MantisEnumTest::DUPLICATE_VALUES_ENUM, 100 ) );
+    }
+
+	/**
+	 * Tests enumerations that contain duplicate labels.
+	 */
+    public function testDuplicateLabelsValuesEnum()
+    {    	
+        $this->assertEquals( 'viewer', MantisEnum::getLabel( MantisEnumTest::DUPLICATE_LABELS_ENUM, 10 ) );
+        $this->assertEquals( 'viewer', MantisEnum::getLabel( MantisEnumTest::DUPLICATE_LABELS_ENUM, 20 ) );
+        $this->assertEquals( '@100@', MantisEnum::getLabel( MantisEnumTest::DUPLICATE_LABELS_ENUM, 100 ) );
+    }
+
+	/**
+	 * Tests enumerations with a single tuple.
+	 */
+    public function testSingleValueEnum()
+    {    	
+        $this->assertEquals( 'viewer', MantisEnum::getLabel( MantisEnumTest::SINGLE_VALUE_ENUM, 10 ) );
+        $this->assertEquals( '@100@', MantisEnum::getLabel( MantisEnumTest::SINGLE_VALUE_ENUM, 100 ) );
+    }
+
+	/**
+	 * Tests enumerations with labels that contain spaces.
+	 */
+    public function testNameWithSpacesEnum()
+    {    	
+        $this->assertEquals( 'first label', MantisEnum::getLabel( MantisEnumTest::NAME_WITH_SPACES_ENUM, 10 ) );
+        $this->assertEquals( 'second label', MantisEnum::getLabel( MantisEnumTest::NAME_WITH_SPACES_ENUM, 20 ) );
+        $this->assertEquals( '@100@', MantisEnum::getLabel( MantisEnumTest::NAME_WITH_SPACES_ENUM, 100 ) );
+    }
+    
+	/**
+	 * Tests enumerations that contain duplicate labels.
+	 */
+    public function testNonTrimmedEnum()
+    {    	
+        $this->assertEquals( 'viewer', MantisEnum::getLabel( MantisEnumTest::NON_TRIMMED_ENUM, 10 ) );
+        $this->assertEquals( 'reporter', MantisEnum::getLabel( MantisEnumTest::NON_TRIMMED_ENUM, 20 ) );
+        $this->assertEquals( '@100@', MantisEnum::getLabel( MantisEnumTest::NON_TRIMMED_ENUM, 100 ) );
+    }
+}
-- 
1.5.6.5

enums_ut_02.patch (59,540 bytes)   

Activities

vboctor

vboctor

2008-12-08 00:27

manager   ~0020290

Reminder sent to: giallu, grangeway, jreese, thraxisp

I've attached a patch with the enum refactoring + unit tests. Let me know your thoughts.

grangeway

grangeway

2008-12-08 18:33

reporter   ~0020297

I've pulled the PRINT->echo change into a separate commit across the whole codebase, in addition, dropped the unused function in the above patch into a separate commit.

Are we going with phpunit for testing?

I know killefix or someone on IRC was asking about using some other framework the other day.

jreese

jreese

2008-12-08 23:32

reporter   ~0020300

Killefiz is advocating the use of Selenium as a testing framework for the entire application and user interface. PHPUnit is more focused method of testing the API's themselves for adherence to some sort of formalized idea of what each function should or should not do.

We actually could benefit quite a bit from using both testing frameworks, as they don't necessarily overlap:

  • If the API does something wrong, and the page script (knowingly, or accidentally) compensates, Selenium can't catch that, but PHPUnit can.
  • If the API is correct, but the page script mishandles data or uses the wrang API functions, PHPUnit can't catch that, but Selenium can.
jreese

jreese

2008-12-08 23:35

reporter   ~0020301

Also, could this patch be rebased onto Paul's latest changes, and then attached as a formatted patch from Git, so that it will preserve commit information? See the dev manual:

http://mantisforge.org/dev/manual/master/en/developers/dev.contrib.submit.html#DEV.CONTRIB.SUBMIT.REPO

vboctor

vboctor

2008-12-10 00:46

manager   ~0020313

Attached is the updated formatted patch.

I agree that we will need to use PHPUnit for white box testing and something like Selenium for black box testing. We might even be able to drive recorded Selenium tests from within PHPUnit fixtures.

The unit tests that were added primarily focused on a couple of MantisEnum methods, during changing the production code, I added more methods. Hence, more tests can be added to test these. However, my goal is to get the first sample in and to agree on a model we follow for other ports.

Related Changesets

MantisBT: master d8829293

2008-12-12 04:22

vboctor


Details Diff
Fixes 0009946: Refactor enumeration handling and add unit tests for it. Affected Issues
0009946
mod - bug_graph_bystatus.php Diff File
mod - adm_permissions_report.php Diff File
mod - core/file_api.php Diff File
add - tests/MantisEnumTest.php Diff File
mod - core/email_api.php Diff File
add - core/classes/MantisEnum.class.php Diff File
mod - manage_config_work_threshold_page.php Diff File
mod - manage_config_email_set.php Diff File
mod - print_all_bug_page_word.php Diff File
mod - core/filter_api.php Diff File
mod - core/helper_api.php Diff File
mod - manage_config_workflow_set.php Diff File
mod - core/summary_api.php Diff File
mod - api/soap/mc_api.php Diff File
mod - manage_config_email_page.php Diff File
mod - manage_config_workflow_page.php Diff File
mod - core/bug_api.php Diff File
mod - api/soap/mc_enum_api.php Diff File
mod - excel_xml_export.php Diff File
mod - core/graph_api.php Diff File
mod - core/utility_api.php Diff File
mod - bug_change_status_page.php Diff File
mod - core/html_api.php Diff File
mod - core/print_api.php Diff File
mod - summary_page.php Diff File
mod - core.php Diff File
mod - manage_config_work_threshold_set.php Diff File