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