View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0013298 | mantisbt | preferences | public | 2011-09-08 18:35 | 2014-09-23 18:05 |
Reporter | jspezeski | Assigned To | dregad | ||
Priority | low | Severity | feature | Reproducibility | N/A |
Status | closed | Resolution | fixed | ||
Product Version | 1.2.7 | ||||
Target Version | 1.2.13 | Fixed in Version | 1.2.13 | ||
Summary | 0013298: commas and multi-dimensional arrays in adm_config_set | ||||
Description | This TODO was in adm_config_set.php TODO: allow multi-dimensional arrays, allow commas and => within stringsI believe I've taken care of the commas and multi-dimensional arrays. | ||||
Tags | patch | ||||
Attached Files | config_set_todo.patch (3,855 bytes)
--- 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; + } /** | ||||
related to | 0011166 | closed | dhx | new configuration option of 'complex' type is created with string type |
related to | 0015721 | closed | grangeway | Functionality to consider porting to master-2.0.x |
has duplicate | 0012491 | closed | atrol | It's not possible to store complex config ararys which elements contains commas |
related to | 0013382 | closed | dregad | Make configuration options editable in adm_config_report |
related to | 0014559 | closed | dregad | Adding filter for "Configuration report" |
related to | 0016931 | closed | dregad | PHPUnit tests for admin config functions |
related to | 0016932 | closed | dregad | Move functions defined in adm_config_set.php to a core API |
Thank you for the report and suggested fix. Would you consider submitting pull requests for this functionality? This would greatly increase the speed of including these changes in MantisBT. Ideally you would submit pull requests for both the master and master-1.2.x branches at https://github.com/mantisbt/mantisbt . |
|
Work in progress available for testing: https://github.com/dregad/mantisbt/tree/manage-config I think there are still a few issues with some corner cases (e.g. the parser matches array(xxx)=>array(xxx) which is not valid) Testing and feedback would be greatly appreciated. |
|
atrol reported an issue with this patch 0014559:0034671: Editing of complex values (for example view_issues_page_columns) is not longer possible. All values are lost, you get only array () I'll push a commit shortly, that should fix this problem. |
|
|
|
Sorry about that, it was a bit late last night when I finished, and I only ran a quick series of tests, none of which had whitespace around the '=>'. The regex did not take this into consideration and as a result what should have been interpreted as an associative array element, was wrongly detected as a string. Just pushed another fix, please try again. |
|
Works now, I tested nothing more than view_issues_page_columns and status_enum_workflow. |
|
Marking as 'acknowledged' not resolved/closed to track that change gets ported to master-2.0.x branch |
|
MantisBT: master-1.2.x efb8b6b8 2011-09-09 10:25 Details Diff |
Support for multi-dimentional arrays in admin_config_set.php This commit adds support for multi-dimentional arrays, as well as correct handling of commas and '=>' within strings. This is based on work by jspezeski; the original code was modified to align with MantisBT coding guidelines, simplification of the recursive function and fixing a couple of errors in regex. Fixes 0013298 |
Affected Issues 0013298 |
|
mod - adm_config_set.php | Diff File | ||
MantisBT: master 8b98640d 2011-09-09 10:25 Details Diff |
Support for multi-dimentional arrays in admin_config_set.php This commit adds support for multi-dimentional arrays, as well as correct handling of commas and '=>' within strings. This is based on work by jspezeski; the original code was modified to align with MantisBT coding guidelines, simplification of the recursive function and fixing a couple of errors in regex. Fixes 0013298 |
Affected Issues 0013298 |
|
mod - adm_config_set.php | Diff File | ||
MantisBT: master-1.2.x d000c4d7 2013-01-09 08:37 Details Diff |
admin_config_set: Revised process_complex_value() function The new code features an improved regex, which deals more efficiently with the parsing of multi-dimensional and associative arrays. Regex are defined as static variables for better performance with repeated and recursive calls Known issue: an invalid definition like 'array(array(1,2)=>array(3,4))' is not properly parsed. Fixes 0013298 |
Affected Issues 0013298 |
|
mod - adm_config_set.php | Diff File | ||
MantisBT: master 0719f32d 2013-01-09 08:37 Details Diff |
admin_config_set: Revised process_complex_value() function The new code features an improved regex, which deals more efficiently with the parsing of multi-dimensional and associative arrays. Regex are defined as static variables for better performance with repeated and recursive calls Known issue: an invalid definition like 'array(array(1,2)=>array(3,4))' is not properly parsed. Fixes 0013298 |
Affected Issues 0013298 |
|
mod - adm_config_set.php | Diff File |