MediaWiki
REL1_19
|
00001 <?php 00032 class ApiQueryInfo extends ApiQueryBase { 00033 00034 private $fld_protection = false, $fld_talkid = false, 00035 $fld_subjectid = false, $fld_url = false, 00036 $fld_readable = false, $fld_watched = false, 00037 $fld_preload = false, $fld_displaytitle = false; 00038 00039 private $params, $titles, $missing, $everything, $pageCounter; 00040 00041 private $pageRestrictions, $pageIsRedir, $pageIsNew, $pageTouched, 00042 $pageLatest, $pageLength; 00043 00044 private $protections, $watched, $talkids, $subjectids, $displaytitles; 00045 00046 private $tokenFunctions; 00047 00048 public function __construct( $query, $moduleName ) { 00049 parent::__construct( $query, $moduleName, 'in' ); 00050 } 00051 00056 public function requestExtraData( $pageSet ) { 00057 global $wgDisableCounters; 00058 00059 $pageSet->requestField( 'page_restrictions' ); 00060 $pageSet->requestField( 'page_is_redirect' ); 00061 $pageSet->requestField( 'page_is_new' ); 00062 if ( !$wgDisableCounters ) { 00063 $pageSet->requestField( 'page_counter' ); 00064 } 00065 $pageSet->requestField( 'page_touched' ); 00066 $pageSet->requestField( 'page_latest' ); 00067 $pageSet->requestField( 'page_len' ); 00068 } 00069 00076 protected function getTokenFunctions() { 00077 // Don't call the hooks twice 00078 if ( isset( $this->tokenFunctions ) ) { 00079 return $this->tokenFunctions; 00080 } 00081 00082 // If we're in JSON callback mode, no tokens can be obtained 00083 if ( !is_null( $this->getMain()->getRequest()->getVal( 'callback' ) ) ) { 00084 return array(); 00085 } 00086 00087 $this->tokenFunctions = array( 00088 'edit' => array( 'ApiQueryInfo', 'getEditToken' ), 00089 'delete' => array( 'ApiQueryInfo', 'getDeleteToken' ), 00090 'protect' => array( 'ApiQueryInfo', 'getProtectToken' ), 00091 'move' => array( 'ApiQueryInfo', 'getMoveToken' ), 00092 'block' => array( 'ApiQueryInfo', 'getBlockToken' ), 00093 'unblock' => array( 'ApiQueryInfo', 'getUnblockToken' ), 00094 'email' => array( 'ApiQueryInfo', 'getEmailToken' ), 00095 'import' => array( 'ApiQueryInfo', 'getImportToken' ), 00096 'watch' => array( 'ApiQueryInfo', 'getWatchToken'), 00097 ); 00098 wfRunHooks( 'APIQueryInfoTokens', array( &$this->tokenFunctions ) ); 00099 return $this->tokenFunctions; 00100 } 00101 00102 public static function getEditToken( $pageid, $title ) { 00103 // We could check for $title->userCan('edit') here, 00104 // but that's too expensive for this purpose 00105 // and would break caching 00106 global $wgUser; 00107 if ( !$wgUser->isAllowed( 'edit' ) ) { 00108 return false; 00109 } 00110 00111 // The edit token is always the same, let's exploit that 00112 static $cachedEditToken = null; 00113 if ( !is_null( $cachedEditToken ) ) { 00114 return $cachedEditToken; 00115 } 00116 00117 $cachedEditToken = $wgUser->getEditToken(); 00118 return $cachedEditToken; 00119 } 00120 00121 public static function getDeleteToken( $pageid, $title ) { 00122 global $wgUser; 00123 if ( !$wgUser->isAllowed( 'delete' ) ) { 00124 return false; 00125 } 00126 00127 static $cachedDeleteToken = null; 00128 if ( !is_null( $cachedDeleteToken ) ) { 00129 return $cachedDeleteToken; 00130 } 00131 00132 $cachedDeleteToken = $wgUser->getEditToken(); 00133 return $cachedDeleteToken; 00134 } 00135 00136 public static function getProtectToken( $pageid, $title ) { 00137 global $wgUser; 00138 if ( !$wgUser->isAllowed( 'protect' ) ) { 00139 return false; 00140 } 00141 00142 static $cachedProtectToken = null; 00143 if ( !is_null( $cachedProtectToken ) ) { 00144 return $cachedProtectToken; 00145 } 00146 00147 $cachedProtectToken = $wgUser->getEditToken(); 00148 return $cachedProtectToken; 00149 } 00150 00151 public static function getMoveToken( $pageid, $title ) { 00152 global $wgUser; 00153 if ( !$wgUser->isAllowed( 'move' ) ) { 00154 return false; 00155 } 00156 00157 static $cachedMoveToken = null; 00158 if ( !is_null( $cachedMoveToken ) ) { 00159 return $cachedMoveToken; 00160 } 00161 00162 $cachedMoveToken = $wgUser->getEditToken(); 00163 return $cachedMoveToken; 00164 } 00165 00166 public static function getBlockToken( $pageid, $title ) { 00167 global $wgUser; 00168 if ( !$wgUser->isAllowed( 'block' ) ) { 00169 return false; 00170 } 00171 00172 static $cachedBlockToken = null; 00173 if ( !is_null( $cachedBlockToken ) ) { 00174 return $cachedBlockToken; 00175 } 00176 00177 $cachedBlockToken = $wgUser->getEditToken(); 00178 return $cachedBlockToken; 00179 } 00180 00181 public static function getUnblockToken( $pageid, $title ) { 00182 // Currently, this is exactly the same as the block token 00183 return self::getBlockToken( $pageid, $title ); 00184 } 00185 00186 public static function getEmailToken( $pageid, $title ) { 00187 global $wgUser; 00188 if ( !$wgUser->canSendEmail() || $wgUser->isBlockedFromEmailUser() ) { 00189 return false; 00190 } 00191 00192 static $cachedEmailToken = null; 00193 if ( !is_null( $cachedEmailToken ) ) { 00194 return $cachedEmailToken; 00195 } 00196 00197 $cachedEmailToken = $wgUser->getEditToken(); 00198 return $cachedEmailToken; 00199 } 00200 00201 public static function getImportToken( $pageid, $title ) { 00202 global $wgUser; 00203 if ( !$wgUser->isAllowedAny( 'import', 'importupload' ) ) { 00204 return false; 00205 } 00206 00207 static $cachedImportToken = null; 00208 if ( !is_null( $cachedImportToken ) ) { 00209 return $cachedImportToken; 00210 } 00211 00212 $cachedImportToken = $wgUser->getEditToken(); 00213 return $cachedImportToken; 00214 } 00215 00216 public static function getWatchToken( $pageid, $title ) { 00217 global $wgUser; 00218 if ( !$wgUser->isLoggedIn() ) { 00219 return false; 00220 } 00221 00222 static $cachedWatchToken = null; 00223 if ( !is_null( $cachedWatchToken ) ) { 00224 return $cachedWatchToken; 00225 } 00226 00227 $cachedWatchToken = $wgUser->getEditToken( 'watch' ); 00228 return $cachedWatchToken; 00229 } 00230 00231 public function execute() { 00232 $this->params = $this->extractRequestParams(); 00233 if ( !is_null( $this->params['prop'] ) ) { 00234 $prop = array_flip( $this->params['prop'] ); 00235 $this->fld_protection = isset( $prop['protection'] ); 00236 $this->fld_watched = isset( $prop['watched'] ); 00237 $this->fld_talkid = isset( $prop['talkid'] ); 00238 $this->fld_subjectid = isset( $prop['subjectid'] ); 00239 $this->fld_url = isset( $prop['url'] ); 00240 $this->fld_readable = isset( $prop['readable'] ); 00241 $this->fld_preload = isset( $prop['preload'] ); 00242 $this->fld_displaytitle = isset( $prop['displaytitle'] ); 00243 } 00244 00245 $pageSet = $this->getPageSet(); 00246 $this->titles = $pageSet->getGoodTitles(); 00247 $this->missing = $pageSet->getMissingTitles(); 00248 $this->everything = $this->titles + $this->missing; 00249 $result = $this->getResult(); 00250 00251 uasort( $this->everything, array( 'Title', 'compare' ) ); 00252 if ( !is_null( $this->params['continue'] ) ) { 00253 // Throw away any titles we're gonna skip so they don't 00254 // clutter queries 00255 $cont = explode( '|', $this->params['continue'] ); 00256 if ( count( $cont ) != 2 ) { 00257 $this->dieUsage( 'Invalid continue param. You should pass the original ' . 00258 'value returned by the previous query', '_badcontinue' ); 00259 } 00260 $conttitle = Title::makeTitleSafe( $cont[0], $cont[1] ); 00261 foreach ( $this->everything as $pageid => $title ) { 00262 if ( Title::compare( $title, $conttitle ) >= 0 ) { 00263 break; 00264 } 00265 unset( $this->titles[$pageid] ); 00266 unset( $this->missing[$pageid] ); 00267 unset( $this->everything[$pageid] ); 00268 } 00269 } 00270 00271 $this->pageRestrictions = $pageSet->getCustomField( 'page_restrictions' ); 00272 $this->pageIsRedir = $pageSet->getCustomField( 'page_is_redirect' ); 00273 $this->pageIsNew = $pageSet->getCustomField( 'page_is_new' ); 00274 00275 global $wgDisableCounters; 00276 00277 if ( !$wgDisableCounters ) { 00278 $this->pageCounter = $pageSet->getCustomField( 'page_counter' ); 00279 } 00280 $this->pageTouched = $pageSet->getCustomField( 'page_touched' ); 00281 $this->pageLatest = $pageSet->getCustomField( 'page_latest' ); 00282 $this->pageLength = $pageSet->getCustomField( 'page_len' ); 00283 00284 // Get protection info if requested 00285 if ( $this->fld_protection ) { 00286 $this->getProtectionInfo(); 00287 } 00288 00289 if ( $this->fld_watched ) { 00290 $this->getWatchedInfo(); 00291 } 00292 00293 // Run the talkid/subjectid query if requested 00294 if ( $this->fld_talkid || $this->fld_subjectid ) { 00295 $this->getTSIDs(); 00296 } 00297 00298 if ( $this->fld_displaytitle ) { 00299 $this->getDisplayTitle(); 00300 } 00301 00302 foreach ( $this->everything as $pageid => $title ) { 00303 $pageInfo = $this->extractPageInfo( $pageid, $title ); 00304 $fit = $result->addValue( array( 00305 'query', 00306 'pages' 00307 ), $pageid, $pageInfo ); 00308 if ( !$fit ) { 00309 $this->setContinueEnumParameter( 'continue', 00310 $title->getNamespace() . '|' . 00311 $title->getText() ); 00312 break; 00313 } 00314 } 00315 } 00316 00323 private function extractPageInfo( $pageid, $title ) { 00324 $pageInfo = array(); 00325 if ( $title->exists() ) { 00326 global $wgDisableCounters; 00327 00328 $pageInfo['touched'] = wfTimestamp( TS_ISO_8601, $this->pageTouched[$pageid] ); 00329 $pageInfo['lastrevid'] = intval( $this->pageLatest[$pageid] ); 00330 $pageInfo['counter'] = $wgDisableCounters 00331 ? "" 00332 : intval( $this->pageCounter[$pageid] ); 00333 $pageInfo['length'] = intval( $this->pageLength[$pageid] ); 00334 00335 if ( $this->pageIsRedir[$pageid] ) { 00336 $pageInfo['redirect'] = ''; 00337 } 00338 if ( $this->pageIsNew[$pageid] ) { 00339 $pageInfo['new'] = ''; 00340 } 00341 } 00342 00343 if ( !is_null( $this->params['token'] ) ) { 00344 $tokenFunctions = $this->getTokenFunctions(); 00345 $pageInfo['starttimestamp'] = wfTimestamp( TS_ISO_8601, time() ); 00346 foreach ( $this->params['token'] as $t ) { 00347 $val = call_user_func( $tokenFunctions[$t], $pageid, $title ); 00348 if ( $val === false ) { 00349 $this->setWarning( "Action '$t' is not allowed for the current user" ); 00350 } else { 00351 $pageInfo[$t . 'token'] = $val; 00352 } 00353 } 00354 } 00355 00356 if ( $this->fld_protection ) { 00357 $pageInfo['protection'] = array(); 00358 if ( isset( $this->protections[$title->getNamespace()][$title->getDBkey()] ) ) { 00359 $pageInfo['protection'] = 00360 $this->protections[$title->getNamespace()][$title->getDBkey()]; 00361 } 00362 $this->getResult()->setIndexedTagName( $pageInfo['protection'], 'pr' ); 00363 } 00364 00365 if ( $this->fld_watched && isset( $this->watched[$title->getNamespace()][$title->getDBkey()] ) ) { 00366 $pageInfo['watched'] = ''; 00367 } 00368 00369 if ( $this->fld_talkid && isset( $this->talkids[$title->getNamespace()][$title->getDBkey()] ) ) { 00370 $pageInfo['talkid'] = $this->talkids[$title->getNamespace()][$title->getDBkey()]; 00371 } 00372 00373 if ( $this->fld_subjectid && isset( $this->subjectids[$title->getNamespace()][$title->getDBkey()] ) ) { 00374 $pageInfo['subjectid'] = $this->subjectids[$title->getNamespace()][$title->getDBkey()]; 00375 } 00376 00377 if ( $this->fld_url ) { 00378 $pageInfo['fullurl'] = wfExpandUrl( $title->getFullURL(), PROTO_CURRENT ); 00379 $pageInfo['editurl'] = wfExpandUrl( $title->getFullURL( 'action=edit' ), PROTO_CURRENT ); 00380 } 00381 if ( $this->fld_readable && $title->userCan( 'read' ) ) { 00382 $pageInfo['readable'] = ''; 00383 } 00384 00385 if ( $this->fld_preload ) { 00386 if ( $title->exists() ) { 00387 $pageInfo['preload'] = ''; 00388 } else { 00389 $text = null; 00390 wfRunHooks( 'EditFormPreloadText', array( &$text, &$title ) ); 00391 00392 $pageInfo['preload'] = $text; 00393 } 00394 } 00395 00396 if ( $this->fld_displaytitle ) { 00397 if ( isset( $this->displaytitles[$title->getArticleId()] ) ) { 00398 $pageInfo['displaytitle'] = $this->displaytitles[$title->getArticleId()]; 00399 } else { 00400 $pageInfo['displaytitle'] = $title->getPrefixedText(); 00401 } 00402 } 00403 00404 return $pageInfo; 00405 } 00406 00410 private function getProtectionInfo() { 00411 global $wgContLang; 00412 $this->protections = array(); 00413 $db = $this->getDB(); 00414 00415 // Get normal protections for existing titles 00416 if ( count( $this->titles ) ) { 00417 $this->resetQueryParams(); 00418 $this->addTables( array( 'page_restrictions', 'page' ) ); 00419 $this->addWhere( 'page_id=pr_page' ); 00420 $this->addFields( array( 'pr_page', 'pr_type', 'pr_level', 00421 'pr_expiry', 'pr_cascade', 'page_namespace', 00422 'page_title' ) ); 00423 $this->addWhereFld( 'pr_page', array_keys( $this->titles ) ); 00424 00425 $res = $this->select( __METHOD__ ); 00426 foreach ( $res as $row ) { 00427 $a = array( 00428 'type' => $row->pr_type, 00429 'level' => $row->pr_level, 00430 'expiry' => $wgContLang->formatExpiry( $row->pr_expiry, TS_ISO_8601 ) 00431 ); 00432 if ( $row->pr_cascade ) { 00433 $a['cascade'] = ''; 00434 } 00435 $this->protections[$row->page_namespace][$row->page_title][] = $a; 00436 00437 // Also check old restrictions 00438 if ( $this->pageRestrictions[$row->pr_page] ) { 00439 $restrictions = explode( ':', trim( $this->pageRestrictions[$row->pr_page] ) ); 00440 foreach ( $restrictions as $restrict ) { 00441 $temp = explode( '=', trim( $restrict ) ); 00442 if ( count( $temp ) == 1 ) { 00443 // old old format should be treated as edit/move restriction 00444 $restriction = trim( $temp[0] ); 00445 00446 if ( $restriction == '' ) { 00447 continue; 00448 } 00449 $this->protections[$row->page_namespace][$row->page_title][] = array( 00450 'type' => 'edit', 00451 'level' => $restriction, 00452 'expiry' => 'infinity', 00453 ); 00454 $this->protections[$row->page_namespace][$row->page_title][] = array( 00455 'type' => 'move', 00456 'level' => $restriction, 00457 'expiry' => 'infinity', 00458 ); 00459 } else { 00460 $restriction = trim( $temp[1] ); 00461 if ( $restriction == '' ) { 00462 continue; 00463 } 00464 $this->protections[$row->page_namespace][$row->page_title][] = array( 00465 'type' => $temp[0], 00466 'level' => $restriction, 00467 'expiry' => 'infinity', 00468 ); 00469 } 00470 } 00471 } 00472 } 00473 } 00474 00475 // Get protections for missing titles 00476 if ( count( $this->missing ) ) { 00477 $this->resetQueryParams(); 00478 $lb = new LinkBatch( $this->missing ); 00479 $this->addTables( 'protected_titles' ); 00480 $this->addFields( array( 'pt_title', 'pt_namespace', 'pt_create_perm', 'pt_expiry' ) ); 00481 $this->addWhere( $lb->constructSet( 'pt', $db ) ); 00482 $res = $this->select( __METHOD__ ); 00483 foreach ( $res as $row ) { 00484 $this->protections[$row->pt_namespace][$row->pt_title][] = array( 00485 'type' => 'create', 00486 'level' => $row->pt_create_perm, 00487 'expiry' => $wgContLang->formatExpiry( $row->pt_expiry, TS_ISO_8601 ) 00488 ); 00489 } 00490 } 00491 00492 // Cascading protections 00493 $images = $others = array(); 00494 foreach ( $this->everything as $title ) { 00495 if ( $title->getNamespace() == NS_FILE ) { 00496 $images[] = $title->getDBkey(); 00497 } else { 00498 $others[] = $title; 00499 } 00500 } 00501 00502 if ( count( $others ) ) { 00503 // Non-images: check templatelinks 00504 $lb = new LinkBatch( $others ); 00505 $this->resetQueryParams(); 00506 $this->addTables( array( 'page_restrictions', 'page', 'templatelinks' ) ); 00507 $this->addFields( array( 'pr_type', 'pr_level', 'pr_expiry', 00508 'page_title', 'page_namespace', 00509 'tl_title', 'tl_namespace' ) ); 00510 $this->addWhere( $lb->constructSet( 'tl', $db ) ); 00511 $this->addWhere( 'pr_page = page_id' ); 00512 $this->addWhere( 'pr_page = tl_from' ); 00513 $this->addWhereFld( 'pr_cascade', 1 ); 00514 00515 $res = $this->select( __METHOD__ ); 00516 foreach ( $res as $row ) { 00517 $source = Title::makeTitle( $row->page_namespace, $row->page_title ); 00518 $this->protections[$row->tl_namespace][$row->tl_title][] = array( 00519 'type' => $row->pr_type, 00520 'level' => $row->pr_level, 00521 'expiry' => $wgContLang->formatExpiry( $row->pr_expiry, TS_ISO_8601 ), 00522 'source' => $source->getPrefixedText() 00523 ); 00524 } 00525 } 00526 00527 if ( count( $images ) ) { 00528 // Images: check imagelinks 00529 $this->resetQueryParams(); 00530 $this->addTables( array( 'page_restrictions', 'page', 'imagelinks' ) ); 00531 $this->addFields( array( 'pr_type', 'pr_level', 'pr_expiry', 00532 'page_title', 'page_namespace', 'il_to' ) ); 00533 $this->addWhere( 'pr_page = page_id' ); 00534 $this->addWhere( 'pr_page = il_from' ); 00535 $this->addWhereFld( 'pr_cascade', 1 ); 00536 $this->addWhereFld( 'il_to', $images ); 00537 00538 $res = $this->select( __METHOD__ ); 00539 foreach ( $res as $row ) { 00540 $source = Title::makeTitle( $row->page_namespace, $row->page_title ); 00541 $this->protections[NS_FILE][$row->il_to][] = array( 00542 'type' => $row->pr_type, 00543 'level' => $row->pr_level, 00544 'expiry' => $wgContLang->formatExpiry( $row->pr_expiry, TS_ISO_8601 ), 00545 'source' => $source->getPrefixedText() 00546 ); 00547 } 00548 } 00549 } 00550 00555 private function getTSIDs() { 00556 $getTitles = $this->talkids = $this->subjectids = array(); 00557 00558 foreach ( $this->everything as $t ) { 00559 if ( MWNamespace::isTalk( $t->getNamespace() ) ) { 00560 if ( $this->fld_subjectid ) { 00561 $getTitles[] = $t->getSubjectPage(); 00562 } 00563 } elseif ( $this->fld_talkid ) { 00564 $getTitles[] = $t->getTalkPage(); 00565 } 00566 } 00567 if ( !count( $getTitles ) ) { 00568 return; 00569 } 00570 00571 $db = $this->getDB(); 00572 00573 // Construct a custom WHERE clause that matches 00574 // all titles in $getTitles 00575 $lb = new LinkBatch( $getTitles ); 00576 $this->resetQueryParams(); 00577 $this->addTables( 'page' ); 00578 $this->addFields( array( 'page_title', 'page_namespace', 'page_id' ) ); 00579 $this->addWhere( $lb->constructSet( 'page', $db ) ); 00580 $res = $this->select( __METHOD__ ); 00581 foreach ( $res as $row ) { 00582 if ( MWNamespace::isTalk( $row->page_namespace ) ) { 00583 $this->talkids[MWNamespace::getSubject( $row->page_namespace )][$row->page_title] = 00584 intval( $row->page_id ); 00585 } else { 00586 $this->subjectids[MWNamespace::getTalk( $row->page_namespace )][$row->page_title] = 00587 intval( $row->page_id ); 00588 } 00589 } 00590 } 00591 00592 private function getDisplayTitle() { 00593 $this->displaytitles = array(); 00594 00595 $pageIds = array_keys( $this->titles ); 00596 00597 if ( !count( $pageIds ) ) { 00598 return; 00599 } 00600 00601 $this->resetQueryParams(); 00602 $this->addTables( 'page_props' ); 00603 $this->addFields( array( 'pp_page', 'pp_value' ) ); 00604 $this->addWhereFld( 'pp_page', $pageIds ); 00605 $this->addWhereFld( 'pp_propname', 'displaytitle' ); 00606 $res = $this->select( __METHOD__ ); 00607 00608 foreach ( $res as $row ) { 00609 $this->displaytitles[$row->pp_page] = $row->pp_value; 00610 } 00611 } 00612 00616 private function getWatchedInfo() { 00617 $user = $this->getUser(); 00618 00619 if ( $user->isAnon() || count( $this->everything ) == 0 ) { 00620 return; 00621 } 00622 00623 $this->watched = array(); 00624 $db = $this->getDB(); 00625 00626 $lb = new LinkBatch( $this->everything ); 00627 00628 $this->resetQueryParams(); 00629 $this->addTables( array( 'watchlist' ) ); 00630 $this->addFields( array( 'wl_title', 'wl_namespace' ) ); 00631 $this->addWhere( array( 00632 $lb->constructSet( 'wl', $db ), 00633 'wl_user' => $user->getID() 00634 ) ); 00635 00636 $res = $this->select( __METHOD__ ); 00637 00638 foreach ( $res as $row ) { 00639 $this->watched[$row->wl_namespace][$row->wl_title] = true; 00640 } 00641 } 00642 00643 public function getCacheMode( $params ) { 00644 $publicProps = array( 00645 'protection', 00646 'talkid', 00647 'subjectid', 00648 'url', 00649 'preload', 00650 'displaytitle', 00651 ); 00652 if ( !is_null( $params['prop'] ) ) { 00653 foreach ( $params['prop'] as $prop ) { 00654 if ( !in_array( $prop, $publicProps ) ) { 00655 return 'private'; 00656 } 00657 } 00658 } 00659 if ( !is_null( $params['token'] ) ) { 00660 return 'private'; 00661 } 00662 return 'public'; 00663 } 00664 00665 public function getAllowedParams() { 00666 return array( 00667 'prop' => array( 00668 ApiBase::PARAM_DFLT => null, 00669 ApiBase::PARAM_ISMULTI => true, 00670 ApiBase::PARAM_TYPE => array( 00671 'protection', 00672 'talkid', 00673 'watched', # private 00674 'subjectid', 00675 'url', 00676 'readable', # private 00677 'preload', 00678 'displaytitle', 00679 // If you add more properties here, please consider whether they 00680 // need to be added to getCacheMode() 00681 ) ), 00682 'token' => array( 00683 ApiBase::PARAM_DFLT => null, 00684 ApiBase::PARAM_ISMULTI => true, 00685 ApiBase::PARAM_TYPE => array_keys( $this->getTokenFunctions() ) 00686 ), 00687 'continue' => null, 00688 ); 00689 } 00690 00691 public function getParamDescription() { 00692 return array( 00693 'prop' => array( 00694 'Which additional properties to get:', 00695 ' protection - List the protection level of each page', 00696 ' talkid - The page ID of the talk page for each non-talk page', 00697 ' watched - List the watched status of each page', 00698 ' subjectid - The page ID of the parent page for each talk page', 00699 ' url - Gives a full URL to the page, and also an edit URL', 00700 ' readable - Whether the user can read this page', 00701 ' preload - Gives the text returned by EditFormPreloadText', 00702 ' displaytitle - Gives the way the page title is actually displayed', 00703 ), 00704 'token' => 'Request a token to perform a data-modifying action on a page', 00705 'continue' => 'When more results are available, use this to continue', 00706 ); 00707 } 00708 00709 public function getDescription() { 00710 return 'Get basic page information such as namespace, title, last touched date, ...'; 00711 } 00712 00713 public function getPossibleErrors() { 00714 return array_merge( parent::getPossibleErrors(), array( 00715 array( 'code' => '_badcontinue', 'info' => 'Invalid continue param. You should pass the original value returned by the previous query' ), 00716 ) ); 00717 } 00718 00719 public function getExamples() { 00720 return array( 00721 'api.php?action=query&prop=info&titles=Main%20Page', 00722 'api.php?action=query&prop=info&inprop=protection&titles=Main%20Page' 00723 ); 00724 } 00725 00726 public function getHelpUrls() { 00727 return 'https://www.mediawiki.org/wiki/API:Properties#info_.2F_in'; 00728 } 00729 00730 public function getVersion() { 00731 return __CLASS__ . ': $Id$'; 00732 } 00733 }