MediaWiki
REL1_22
|
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 00072 return strcmp( $a, $b ); 00073 } ); 00074 $reqStr = http_build_query( $request ); 00075 //$reqStr = str_replace( '&', ' & ', $reqStr ); 00076 $this->assertLessThan( $expectedCount, $count, "$id more data: $reqStr" ); 00077 if ( $this->mVerbose ) { 00078 print "$id (#$count): $reqStr\n"; 00079 } 00080 try { 00081 $data = $this->doApiRequest( $request ); 00082 } catch ( Exception $e ) { 00083 throw new Exception( "$id on $count", 0, $e ); 00084 } 00085 $data = $data[0]; 00086 if ( isset( $data['warnings'] ) ) { 00087 $warnings = json_encode( $data['warnings'] ); 00088 $this->fail( "$id Warnings on #$count in $reqStr\n$warnings" ); 00089 } 00090 $this->assertArrayHasKey( 'query', $data, "$id no 'query' on #$count in $reqStr" ); 00091 if ( isset( $data['continue'] ) ) { 00092 $continue = $data['continue']; 00093 unset( $data['continue'] ); 00094 } else { 00095 $continue = array(); 00096 } 00097 if ( $this->mVerbose ) { 00098 $this->printResult( $data ); 00099 } 00100 $this->mergeResult( $result, $data ); 00101 $count++; 00102 if ( empty( $continue ) ) { 00103 // $this->assertEquals( $expectedCount, $count, "$id finished early" ); 00104 if ( $expectedCount > $count ) { 00105 print "***** $id Finished early in $count turns. $expectedCount was expected\n"; 00106 } 00107 00108 return $result; 00109 } elseif ( !$useContinue ) { 00110 $this->assertFalse( 'Non-smart query must be requested all at once' ); 00111 } 00112 } while ( true ); 00113 } 00114 00115 private function printResult( $data ) { 00116 $q = $data['query']; 00117 $print = array(); 00118 if ( isset( $q['pages'] ) ) { 00119 foreach ( $q['pages'] as $p ) { 00120 $m = $p['title']; 00121 if ( isset( $p['links'] ) ) { 00122 $m .= '/[' . implode( ',', array_map( 00123 function ( $v ) { 00124 return $v['title']; 00125 }, 00126 $p['links'] ) ) . ']'; 00127 } 00128 if ( isset( $p['categories'] ) ) { 00129 $m .= '/(' . implode( ',', array_map( 00130 function ( $v ) { 00131 return str_replace( 'Category:', '', $v['title'] ); 00132 }, 00133 $p['categories'] ) ) . ')'; 00134 } 00135 $print[] = $m; 00136 } 00137 } 00138 if ( isset( $q['allcategories'] ) ) { 00139 $print[] = '*Cats/(' . implode( ',', array_map( 00140 function ( $v ) { 00141 return $v['*']; 00142 }, 00143 $q['allcategories'] ) ) . ')'; 00144 } 00145 self::GetItems( $q, 'allpages', 'Pages', $print ); 00146 self::GetItems( $q, 'alllinks', 'Links', $print ); 00147 self::GetItems( $q, 'alltransclusions', 'Trnscl', $print ); 00148 print ' ' . implode( ' ', $print ) . "\n"; 00149 } 00150 00151 private static function GetItems( $q, $moduleName, $name, &$print ) { 00152 if ( isset( $q[$moduleName] ) ) { 00153 $print[] = "*$name/[" . implode( ',', 00154 array_map( function ( $v ) { 00155 return $v['title']; 00156 }, 00157 $q[$moduleName] ) ) . ']'; 00158 } 00159 } 00160 00167 protected function mergeResult( &$results, $newResult, $numericIds = false ) { 00168 $this->assertEquals( is_array( $results ), is_array( $newResult ), 'Type of result and data do not match' ); 00169 if ( !is_array( $results ) ) { 00170 $this->assertEquals( $results, $newResult, 'Repeated result must be the same as before' ); 00171 } else { 00172 $sort = null; 00173 foreach ( $newResult as $key => $value ) { 00174 if ( !$numericIds && $sort === null ) { 00175 if ( !is_array( $value ) ) { 00176 $sort = false; 00177 } elseif ( array_key_exists( 'title', $value ) ) { 00178 $sort = function ( $a, $b ) { 00179 return strcmp( $a['title'], $b['title'] ); 00180 }; 00181 } else { 00182 $sort = false; 00183 } 00184 } 00185 $keyExists = array_key_exists( $key, $results ); 00186 if ( is_numeric( $key ) ) { 00187 if ( $numericIds ) { 00188 if ( !$keyExists ) { 00189 $results[$key] = $value; 00190 } else { 00191 $this->mergeResult( $results[$key], $value ); 00192 } 00193 } else { 00194 $results[] = $value; 00195 } 00196 } elseif ( !$keyExists ) { 00197 $results[$key] = $value; 00198 } else { 00199 $this->mergeResult( $results[$key], $value, $key === 'pages' ); 00200 } 00201 } 00202 if ( $numericIds ) { 00203 ksort( $results, SORT_NUMERIC ); 00204 } elseif ( $sort !== null && $sort !== false ) { 00205 uasort( $results, $sort ); 00206 } 00207 } 00208 } 00209 }