--- adm_config_set.php	Tue Apr 05 11:24:17 2011
+++ adm_config_set.php	Thu Sep 08 15:22:13 2011
@@ -85,34 +85,104 @@
 		# TODO: allow multi-dimensional arrays, allow commas and => within strings
 		$t_full_string = trim( $f_value );
 		if ( preg_match('/array[\s]*\((.*)\)/s', $t_full_string, $t_match ) === 1 ) {
-			// we have an array here
-			$t_values = explode( ',', trim( $t_match[1] ) );
+			$t_value=prepare_array_recursive($t_match);
+		} else {
+			// scalar value
+			$t_value = constant_replace( trim( $t_full_string ) );
+		}
+	}
+
+	config_set( $f_config_option, $t_value, $f_user_id, $f_project_id );
+
+	form_security_purge( 'adm_config_set' );
+
+	print_successful_redirect( 'adm_config_report.php' );
+
+	/**
+	 * Helper function to support multi-dimensional arrays
+	 */
+	function prepare_array_recursive ($p_array) {
+		$t_match = $p_array;
+		// separate the string into array elements
+		$t_values = special_split($t_match[1]);
+
 			foreach ( $t_values as $key => $value ) {
 				if ( !trim( $value ) ) {
 					continue;
 				}
-				$t_split = explode( '=>', $value, 2 );
+			$t_split = explode( '/=>/', $value, 2 );
 				if ( count( $t_split ) == 2 ) {
 					// associative array
-					$t_new_key = constant_replace( trim( $t_split[0], " \t\n\r\0\x0B\"'" ) );
+				if ( preg_match('/array[\s]*\((.*)\)/s', $t_split[1], $t_match ) === 1 ) {
+					// nested array
+					$t_new_value=prepare_array_recursive($t_match);
+				} 
+				else {
+					// regular element
 					$t_new_value = constant_replace( trim( $t_split[1], " \t\n\r\0\x0B\"'" ) );
+				}
+				$t_new_key = constant_replace( trim( $t_split[0], " \t\n\r\0\x0B\"'" ) );
 					$t_value[ $t_new_key ] = $t_new_value;
 				} else {
 					// regular array
-					$t_value[ $key ] = constant_replace( trim( $value, " \t\n\r\0\x0B\"'" ) );
+				if ( preg_match('/array[\s]*\((.*)\)/s', $value, $t_match ) === 1 ) {
+					// nested array
+					$t_new_value=prepare_array_recursive($t_match);
+				} else {
+					// regular element
+					$t_new_value = constant_replace( trim($value, " \t\n\r\0\x0B\"'" ) );
 				}
+				$t_value[ $key ] = $t_new_value;
 			}
-		} else {
-			// scalar value
-			$t_value = constant_replace( trim( $t_full_string ) );
 		}
+		return $t_value;
 	}
 
-	config_set( $f_config_option, $t_value, $f_user_id, $f_project_id );
-
-	form_security_purge( 'adm_config_set' );
+	/**
+	 * Split by commas, but ignore commas that are within quotes or parenthesis.
+	 * Ignoring commas within parenthesis helps allow for multi-dimensional arrays.
+	 */
+	function special_split ($p_string) {
+		$t_values=array();
+		$t_array_element = "";
+		$t_paren_level = 0;
+		$t_inside_quote = False;
+		$t_escape_next = False;
 
-	print_successful_redirect( 'adm_config_report.php' );
+		foreach (str_split(trim($p_string)) as $character) {
+			if ($t_escape_next) {
+				$t_array_element .= $character;
+				$t_escape_next= False;
+			} else
+			if ($character == "," && $t_paren_level==0 && !$t_inside_quote) {
+				array_push($t_values,$t_array_element);
+				$t_array_element = "";
+			} 
+			else {
+				if ($character == "(" && !$t_inside_quote) {
+					$t_paren_level ++;
+				} else
+				if ($character == ")" && !$t_inside_quote) {
+					$t_paren_level --;
+				} else
+				if ($character == "'") {
+					$t_inside_quote = !$t_inside_quote;
+				} else
+				// escape character
+				if ($character == "\\") {
+					$t_escape_next = True;
+					// keep the escape if the string will be going through another recursion
+					if ($t_paren_level>0) {
+						$t_array_element .= $character;
+					}
+					continue;
+				}
+				$t_array_element .= $character;
+			}
+		}
+		array_push($t_values,$t_array_element);
+		return $t_values;
+	}
 
 
 	/**
