aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatěj Grabovský <mgrabovsky@users.mediawiki.org>2011-06-23 15:25:07 +0000
committerMatěj Grabovský <mgrabovsky@users.mediawiki.org>2011-06-23 15:25:07 +0000
commit09da27efa2cacb16252fb43f4ec11d0a118e7129 (patch)
treedd9c6ba2bbea6f0e77f574c79cf1ebf54b5481af
parent1682c80f1f36c1a59777b2f026c5c543c0e49385 (diff)
downloadmediawikicore-09da27efa2cacb16252fb43f4ec11d0a118e7129.tar.gz
mediawikicore-09da27efa2cacb16252fb43f4ec11d0a118e7129.zip
wfArrayToCGI() and wfCgiToArray() now handle nested and associative arrays almost correctly
The only problem is that all the indexes have to be set, thus "key[]=value" won't get parsed correctly and array( 'key' => array( 'value' ) ) will transform to "key[0]=value". Related bug 28928 and bug 22989.
Notes
Notes: http://mediawiki.org/wiki/Special:Code/MediaWiki/90661
-rw-r--r--RELEASE-NOTES-1.192
-rw-r--r--includes/GlobalFunctions.php43
-rw-r--r--tests/phpunit/includes/GlobalTest.php12
3 files changed, 46 insertions, 11 deletions
diff --git a/RELEASE-NOTES-1.19 b/RELEASE-NOTES-1.19
index e8d54df0df9f..4625e781009a 100644
--- a/RELEASE-NOTES-1.19
+++ b/RELEASE-NOTES-1.19
@@ -115,6 +115,8 @@ production.
* (bug 29507) Change 'image link' to 'file link' in Special:Whatlinkshere
* If the db is really screwed up, and doesn't have a recentchanges table,
make the updater throw an exception instead of a fatal.
+* wfArrayToCGI() and wfCgiToArray() now handle nested and associative arrays
+ correctly
=== API changes in 1.19 ===
* BREAKING CHANGE: action=watch now requires POST and token.
diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php
index 287167611239..bca5ca0cdc6b 100644
--- a/includes/GlobalFunctions.php
+++ b/includes/GlobalFunctions.php
@@ -318,9 +318,10 @@ function wfUrlencode( $s ) {
*
* @param $array1 Array( String|Array )
* @param $array2 Array( String|Array )
+ * @param $prefix String
* @return String
*/
-function wfArrayToCGI( $array1, $array2 = null ) {
+function wfArrayToCGI( $array1, $array2 = null, $prefix = '' ) {
if ( !is_null( $array2 ) ) {
$array1 = $array1 + $array2;
}
@@ -331,20 +332,25 @@ function wfArrayToCGI( $array1, $array2 = null ) {
if ( $cgi != '' ) {
$cgi .= '&';
}
+ if ( $prefix !== '' ) {
+ $key = $prefix . "[$key]";
+ }
if ( is_array( $value ) ) {
$firstTime = true;
- foreach ( $value as $v ) {
- $cgi .= ( $firstTime ? '' : '&') .
- urlencode( $key . '[]' ) . '=' .
- urlencode( $v );
+ foreach ( $value as $k => $v ) {
+ $cgi .= $firstTime ? '' : '&';
+ if ( is_array( $v ) ) {
+ $cgi .= wfArrayToCGI( $v, null, $key . "[$k]" );
+ } else {
+ $cgi .= urlencode( $key . "[$k]" ) . '=' . urlencode( $v );
+ }
$firstTime = false;
}
} else {
if ( is_object( $value ) ) {
$value = $value->__toString();
}
- $cgi .= urlencode( $key ) . '=' .
- urlencode( $value );
+ $cgi .= urlencode( $key ) . '=' . urlencode( $value );
}
}
}
@@ -362,19 +368,34 @@ function wfArrayToCGI( $array1, $array2 = null ) {
* @return array Array version of input
*/
function wfCgiToArray( $query ) {
- if( isset( $query[0] ) && $query[0] == '?' ) {
+ if ( isset( $query[0] ) && $query[0] == '?' ) {
$query = substr( $query, 1 );
}
$bits = explode( '&', $query );
$ret = array();
- foreach( $bits as $bit ) {
- if( $bit === '' ) {
+ foreach ( $bits as $bit ) {
+ if ( $bit === '' ) {
continue;
}
list( $key, $value ) = explode( '=', $bit );
$key = urldecode( $key );
$value = urldecode( $value );
- $ret[$key] = $value;
+ if ( strpos( $key, '[' ) !== false ) {
+ $keys = array_reverse( explode( '[', $key ) );
+ $key = array_pop( $keys );
+ $temp = $value;
+ foreach ( $keys as $k ) {
+ $k = substr( $k, 0, -1 );
+ $temp = array( $k => $temp );
+ }
+ if ( isset( $ret[$key] ) ) {
+ $ret[$key] = array_merge( $ret[$key], $temp );
+ } else {
+ $ret[$key] = $temp;
+ }
+ } else {
+ $ret[$key] = $value;
+ }
}
return $ret;
}
diff --git a/tests/phpunit/includes/GlobalTest.php b/tests/phpunit/includes/GlobalTest.php
index 5e6ae847c575..b06dbf150908 100644
--- a/tests/phpunit/includes/GlobalTest.php
+++ b/tests/phpunit/includes/GlobalTest.php
@@ -102,6 +102,18 @@ class GlobalTest extends MediaWikiTestCase {
wfArrayToCGI(
array( 'baz' => 'AT&T', 'ignore' => '' ),
array( 'foo' => 'bar', 'baz' => 'overridden value' ) ) );
+ $this->assertEquals(
+ "path%5B0%5D=wiki&path%5B1%5D=test&cfg%5Bservers%5D%5Bhttp%5D=localhost",
+ wfArrayToCGI( array(
+ 'path' => array( 'wiki', 'test' ),
+ 'cfg' => array( 'servers' => array( 'http' => 'localhost' ) ) ) ) );
+ }
+
+ function testCgiToArray() {
+ $this->assertEquals(
+ array( 'path' => array( 'wiki', 'test' ),
+ 'cfg' => array( 'servers' => array( 'http' => 'localhost' ) ) ),
+ wfCgiToArray( 'path%5B0%5D=wiki&path%5B1%5D=test&cfg%5Bservers%5D%5Bhttp%5D=localhost' ) );
}
function testMimeTypeMatch() {