--- 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; + } /**