http://www.mediawiki.org/wiki/Special:Code/MediaWiki/90661

Revision: 90661
Author:   mgrabovsky
Date:     2011-06-23 15:25:07 +0000 (Thu, 23 Jun 2011)
Log Message:
-----------
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.

Modified Paths:
--------------
    trunk/phase3/RELEASE-NOTES-1.19
    trunk/phase3/includes/GlobalFunctions.php
    trunk/phase3/tests/phpunit/includes/GlobalTest.php

Modified: trunk/phase3/RELEASE-NOTES-1.19
===================================================================
--- trunk/phase3/RELEASE-NOTES-1.19     2011-06-23 14:04:05 UTC (rev 90660)
+++ trunk/phase3/RELEASE-NOTES-1.19     2011-06-23 15:25:07 UTC (rev 90661)
@@ -115,6 +115,8 @@
 * (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.

Modified: trunk/phase3/includes/GlobalFunctions.php
===================================================================
--- trunk/phase3/includes/GlobalFunctions.php   2011-06-23 14:04:05 UTC (rev 
90660)
+++ trunk/phase3/includes/GlobalFunctions.php   2011-06-23 15:25:07 UTC (rev 
90661)
@@ -318,9 +318,10 @@
  *
  * @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 @@
                        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 @@
  * @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;
 }

Modified: trunk/phase3/tests/phpunit/includes/GlobalTest.php
===================================================================
--- trunk/phase3/tests/phpunit/includes/GlobalTest.php  2011-06-23 14:04:05 UTC 
(rev 90660)
+++ trunk/phase3/tests/phpunit/includes/GlobalTest.php  2011-06-23 15:25:07 UTC 
(rev 90661)
@@ -102,8 +102,20 @@
                        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() {
                $this->assertEquals(
                        'text/html',


_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to