MediaWiki  REL1_21
ApiQueryContinueTestBase.php
Go to the documentation of this file.
00001 <?php
00027 require_once( 'ApiQueryTestBase.php' );
00028 
00029 abstract class ApiQueryContinueTestBase extends ApiQueryTestBase {
00030 
00034         protected $mVerbose = false;
00035 
00039         protected function checkC( $expected, $params, $expectedCount, $id, $continue = true  ) {
00040                 $result = $this->query( $params, $expectedCount, $id, $continue );
00041                 $this->assertResult( $expected, $result, $id );
00042         }
00043 
00053         protected function query( $params, $expectedCount, $id, $useContinue = true ) {
00054                 if ( isset( $params['action'] ) ) {
00055                         $this->assertEquals( 'query', $params['action'], 'Invalid query action');
00056                 } else {
00057                         $params['action'] = 'query';
00058                 }
00059                 if ( $useContinue && !isset( $params['continue'] ) ) {
00060                         $params['continue'] = '';
00061                 }
00062                 $count = 0;
00063                 $result = array();
00064                 $continue = array();
00065                 do {
00066                         $request = array_merge( $params, $continue );
00067                         uksort( $request, function( $a, $b ) {
00068                                 // put 'continue' params at the end - lazy method
00069                                 $a = strpos( $a, 'continue' ) !== false ? 'zzz ' . $a : $a;
00070                                 $b = strpos( $b, 'continue' ) !== false ? 'zzz ' . $b : $b;
00071                                 return strcmp( $a, $b );
00072                         } );
00073                         $reqStr = http_build_query( $request );
00074                         //$reqStr = str_replace( '&', ' & ', $reqStr );
00075                         $this->assertLessThan( $expectedCount, $count, "$id more data: $reqStr" );
00076                         if ( $this->mVerbose ) {
00077                                 print ("$id (#$count): $reqStr\n");
00078                         }
00079                         try {
00080                                 $data = $this->doApiRequest( $request );
00081                         } catch ( Exception $e ) {
00082                                 throw new Exception( "$id on $count", 0, $e );
00083                         }
00084                         $data = $data[0];
00085                         if ( isset( $data['warnings'] ) ) {
00086                                 $warnings = json_encode( $data['warnings'] );
00087                                 $this->fail( "$id Warnings on #$count in $reqStr\n$warnings" );
00088                         }
00089                         $this->assertArrayHasKey( 'query', $data, "$id no 'query' on #$count in $reqStr" );
00090                         if ( isset( $data['continue'] ) ) {
00091                                 $continue = $data['continue'];
00092                                 unset( $data['continue'] );
00093                         } else {
00094                                 $continue = array();
00095                         }
00096                         if ( $this->mVerbose ) {
00097                                 $this->printResult( $data );
00098                         }
00099                         $this->mergeResult( $result, $data );
00100                         $count++;
00101                         if ( empty( $continue ) ) {
00102                                 // $this->assertEquals( $expectedCount, $count, "$id finished early" );
00103                                 if ( $expectedCount > $count ) {
00104                                         print "***** $id Finished early in $count turns. $expectedCount was expected\n";
00105                                 }
00106                                 return $result;
00107                         } elseif ( !$useContinue ) {
00108                                 $this->assertFalse( 'Non-smart query must be requested all at once' );
00109                         }
00110                 } while( true );
00111         }
00112 
00113         private function printResult( $data ) {
00114                 $q = $data['query'];
00115                 $print = array();
00116                 if (isset($q['pages'])) {
00117                         foreach ($q['pages'] as $p) {
00118                                 $m = $p['title'];
00119                                 if (isset($p['links'])) {
00120                                         $m .= '/[' . implode(',', array_map(
00121                                                 function ($v) {
00122                                                         return $v['title'];
00123                                                 },
00124                                                 $p['links'])) . ']';
00125                                 }
00126                                 if (isset($p['categories'])) {
00127                                         $m .= '/(' . implode(',', array_map(
00128                                                 function ($v) {
00129                                                         return str_replace('Category:', '', $v['title']);
00130                                                 },
00131                                                 $p['categories'])) . ')';
00132                                 }
00133                                 $print[] = $m;
00134                         }
00135                 }
00136                 if (isset($q['allcategories'])) {
00137                         $print[] = '*Cats/(' . implode(',', array_map(
00138                                 function ($v) { return $v['*']; },
00139                                 $q['allcategories'])) . ')';
00140                 }
00141                 self::GetItems( $q, 'allpages', 'Pages', $print );
00142                 self::GetItems( $q, 'alllinks', 'Links', $print );
00143                 self::GetItems( $q, 'alltransclusions', 'Trnscl', $print );
00144                 print(' ' . implode('  ', $print) . "\n");
00145         }
00146 
00147         private static function GetItems( $q, $moduleName, $name, &$print ) {
00148                 if (isset($q[$moduleName])) {
00149                         $print[] = "*$name/[" . implode(',',
00150                                 array_map( function ($v) { return $v['title']; },
00151                                                 $q[$moduleName])) . ']';
00152                 }
00153         }
00154 
00161         protected function mergeResult( &$results, $newResult, $numericIds = false ) {
00162                 $this->assertEquals( is_array( $results ), is_array( $newResult ), 'Type of result and data do not match' );
00163                 if ( !is_array( $results ) ) {
00164                         $this->assertEquals( $results, $newResult, 'Repeated result must be the same as before' );
00165                 } else {
00166                         $sort = null;
00167                         foreach( $newResult as $key => $value ) {
00168                                 if ( !$numericIds && $sort === null ) {
00169                                         if ( !is_array( $value ) ) {
00170                                                 $sort = false;
00171                                         } elseif ( array_key_exists( 'title', $value ) ) {
00172                                                 $sort = function( $a, $b ) {
00173                                                         return strcmp( $a['title'], $b['title'] );
00174                                                 };
00175                                         } else {
00176                                                 $sort = false;
00177                                         }
00178                                 }
00179                                 $keyExists = array_key_exists( $key, $results );
00180                                 if ( is_numeric( $key ) ) {
00181                                         if ( $numericIds ) {
00182                                                 if ( !$keyExists ) {
00183                                                         $results[$key] = $value;
00184                                                 } else {
00185                                                         $this->mergeResult( $results[$key], $value );
00186                                                 }
00187                                         } else {
00188                                                 $results[] = $value;
00189                                         }
00190                                 } elseif ( !$keyExists ) {
00191                                         $results[$key] = $value;
00192                                 } else {
00193                                         $this->mergeResult( $results[$key], $value, $key === 'pages' );
00194                                 }
00195                         }
00196                         if ( $numericIds ) {
00197                                 ksort( $results, SORT_NUMERIC );
00198                         } elseif ( $sort !== null && $sort !== false ) {
00199                                 uasort( $results, $sort );
00200                         }
00201                 }
00202         }
00203 }