52 parent::__construct(
$query, $moduleName,
'in' );
60 global $wgDisableCounters, $wgContentHandlerUseDB;
62 $pageSet->requestField(
'page_restrictions' );
64 if ( !$pageSet->isResolvingRedirects() ) {
65 $pageSet->requestField(
'page_is_redirect' );
67 $pageSet->requestField(
'page_is_new' );
68 if ( !$wgDisableCounters ) {
69 $pageSet->requestField(
'page_counter' );
71 $pageSet->requestField(
'page_touched' );
72 $pageSet->requestField(
'page_latest' );
73 $pageSet->requestField(
'page_len' );
74 if ( $wgContentHandlerUseDB ) {
75 $pageSet->requestField(
'page_content_model' );
87 if ( isset( $this->tokenFunctions ) ) {
96 $this->tokenFunctions =
array(
97 'edit' =>
array(
'ApiQueryInfo',
'getEditToken' ),
98 'delete' =>
array(
'ApiQueryInfo',
'getDeleteToken' ),
99 'protect' =>
array(
'ApiQueryInfo',
'getProtectToken' ),
100 'move' =>
array(
'ApiQueryInfo',
'getMoveToken' ),
101 'block' =>
array(
'ApiQueryInfo',
'getBlockToken' ),
102 'unblock' =>
array(
'ApiQueryInfo',
'getUnblockToken' ),
103 'email' =>
array(
'ApiQueryInfo',
'getEmailToken' ),
104 'import' =>
array(
'ApiQueryInfo',
'getImportToken' ),
105 'watch' =>
array(
'ApiQueryInfo',
'getWatchToken' ),
123 if ( !
$wgUser->isAllowed(
'edit' ) ) {
137 if ( !
$wgUser->isAllowed(
'delete' ) ) {
151 if ( !
$wgUser->isAllowed(
'protect' ) ) {
165 if ( !
$wgUser->isAllowed(
'move' ) ) {
179 if ( !
$wgUser->isAllowed(
'block' ) ) {
198 if ( !
$wgUser->canSendEmail() ||
$wgUser->isBlockedFromEmailUser() ) {
212 if ( !
$wgUser->isAllowedAny(
'import',
'importupload' ) ) {
226 if ( !
$wgUser->isLoggedIn() ) {
240 if ( !
$wgUser->isLoggedIn() ) {
254 if ( !is_null( $this->params[
'prop'] ) ) {
255 $prop = array_flip( $this->params[
'prop'] );
256 $this->fld_protection = isset( $prop[
'protection'] );
257 $this->fld_watched = isset( $prop[
'watched'] );
258 $this->fld_watchers = isset( $prop[
'watchers'] );
259 $this->fld_notificationtimestamp = isset( $prop[
'notificationtimestamp'] );
260 $this->fld_talkid = isset( $prop[
'talkid'] );
261 $this->fld_subjectid = isset( $prop[
'subjectid'] );
262 $this->fld_url = isset( $prop[
'url'] );
263 $this->fld_readable = isset( $prop[
'readable'] );
264 $this->fld_preload = isset( $prop[
'preload'] );
265 $this->fld_displaytitle = isset( $prop[
'displaytitle'] );
269 $this->titles = $pageSet->getGoodTitles();
270 $this->missing = $pageSet->getMissingTitles();
274 uasort( $this->everything,
array(
'Title',
'compare' ) );
275 if ( !is_null( $this->params[
'continue'] ) ) {
278 $cont = explode(
'|', $this->params[
'continue'] );
281 foreach ( $this->everything
as $pageid =>
$title ) {
285 unset( $this->titles[$pageid] );
286 unset( $this->missing[$pageid] );
287 unset( $this->everything[$pageid] );
291 $this->pageRestrictions = $pageSet->getCustomField(
'page_restrictions' );
293 $this->pageIsRedir = !$pageSet->isResolvingRedirects()
294 ? $pageSet->getCustomField(
'page_is_redirect' )
296 $this->pageIsNew = $pageSet->getCustomField(
'page_is_new' );
298 global $wgDisableCounters;
300 if ( !$wgDisableCounters ) {
301 $this->pageCounter = $pageSet->getCustomField(
'page_counter' );
303 $this->pageTouched = $pageSet->getCustomField(
'page_touched' );
304 $this->pageLatest = $pageSet->getCustomField(
'page_latest' );
305 $this->pageLength = $pageSet->getCustomField(
'page_len' );
308 if ( $this->fld_protection ) {
312 if ( $this->fld_watched || $this->fld_notificationtimestamp ) {
316 if ( $this->fld_watchers ) {
321 if ( $this->fld_talkid || $this->fld_subjectid ) {
325 if ( $this->fld_displaytitle ) {
330 foreach ( $this->everything
as $pageid =>
$title ) {
335 ), $pageid, $pageInfo );
338 $title->getNamespace() .
'|' .
354 $titleExists = $pageid > 0;
355 $ns =
$title->getNamespace();
356 $dbkey =
$title->getDBkey();
358 $pageInfo[
'contentmodel'] =
$title->getContentModel();
359 $pageInfo[
'pagelanguage'] =
$title->getPageLanguage()->getCode();
361 if ( $titleExists ) {
362 global $wgDisableCounters;
365 $pageInfo[
'lastrevid'] = intval( $this->pageLatest[$pageid] );
366 $pageInfo[
'counter'] = $wgDisableCounters
368 : intval( $this->pageCounter[$pageid] );
369 $pageInfo[
'length'] = intval( $this->pageLength[$pageid] );
371 if ( isset( $this->pageIsRedir[$pageid] ) && $this->pageIsRedir[$pageid] ) {
372 $pageInfo[
'redirect'] =
'';
374 if ( $this->pageIsNew[$pageid] ) {
375 $pageInfo[
'new'] =
'';
379 if ( !is_null( $this->params[
'token'] ) ) {
382 foreach ( $this->params[
'token']
as $t ) {
384 if ( $val ===
false ) {
385 $this->
setWarning(
"Action '$t' is not allowed for the current user" );
387 $pageInfo[
$t .
'token'] = $val;
392 if ( $this->fld_protection ) {
393 $pageInfo[
'protection'] =
array();
394 if ( isset( $this->protections[$ns][$dbkey] ) ) {
395 $pageInfo[
'protection'] =
396 $this->protections[$ns][$dbkey];
398 $this->
getResult()->setIndexedTagName( $pageInfo[
'protection'],
'pr' );
401 if ( $this->fld_watched && isset( $this->watched[$ns][$dbkey] ) ) {
402 $pageInfo[
'watched'] =
'';
405 if ( $this->fld_watchers ) {
406 if ( isset( $this->watchers[$ns][$dbkey] ) ) {
407 $pageInfo[
'watchers'] = $this->watchers[$ns][$dbkey];
408 } elseif ( $this->showZeroWatchers ) {
409 $pageInfo[
'watchers'] = 0;
413 if ( $this->fld_notificationtimestamp ) {
414 $pageInfo[
'notificationtimestamp'] =
'';
415 if ( isset( $this->notificationtimestamps[$ns][$dbkey] ) ) {
416 $pageInfo[
'notificationtimestamp'] =
421 if ( $this->fld_talkid && isset( $this->talkids[$ns][$dbkey] ) ) {
422 $pageInfo[
'talkid'] = $this->talkids[$ns][$dbkey];
425 if ( $this->fld_subjectid && isset( $this->subjectids[$ns][$dbkey] ) ) {
426 $pageInfo[
'subjectid'] = $this->subjectids[$ns][$dbkey];
429 if ( $this->fld_url ) {
433 if ( $this->fld_readable &&
$title->userCan(
'read', $this->getUser() ) ) {
434 $pageInfo[
'readable'] =
'';
437 if ( $this->fld_preload ) {
438 if ( $titleExists ) {
439 $pageInfo[
'preload'] =
'';
444 $pageInfo[
'preload'] = $text;
448 if ( $this->fld_displaytitle ) {
449 if ( isset( $this->displaytitles[$pageid] ) ) {
450 $pageInfo[
'displaytitle'] = $this->displaytitles[$pageid];
452 $pageInfo[
'displaytitle'] =
$title->getPrefixedText();
464 $this->protections =
array();
465 $db = $this->
getDB();
468 if ( count( $this->titles ) ) {
472 'pr_expiry',
'pr_cascade' ) );
473 $this->
addWhereFld(
'pr_page', array_keys( $this->titles ) );
476 foreach (
$res as $row ) {
478 $title = $this->titles[$row->pr_page];
480 'type' => $row->pr_type,
481 'level' => $row->pr_level,
484 if ( $row->pr_cascade ) {
487 $this->protections[
$title->getNamespace()][
$title->getDBkey()][] = $a;
490 foreach ( $this->titles
as $pageId =>
$title ) {
491 if ( $this->pageRestrictions[$pageId] ) {
492 $namespace =
$title->getNamespace();
493 $dbKey =
$title->getDBkey();
494 $restrictions = explode(
':', trim( $this->pageRestrictions[$pageId] ) );
495 foreach ( $restrictions
as $restrict ) {
496 $temp = explode(
'=', trim( $restrict ) );
497 if ( count( $temp ) == 1 ) {
499 $restriction = trim( $temp[0] );
501 if ( $restriction ==
'' ) {
504 $this->protections[$namespace][$dbKey][] =
array(
506 'level' => $restriction,
507 'expiry' =>
'infinity',
509 $this->protections[$namespace][$dbKey][] =
array(
511 'level' => $restriction,
512 'expiry' =>
'infinity',
515 $restriction = trim( $temp[1] );
516 if ( $restriction ==
'' ) {
519 $this->protections[$namespace][$dbKey][] =
array(
521 'level' => $restriction,
522 'expiry' =>
'infinity',
531 if ( count( $this->missing ) ) {
535 $this->
addFields(
array(
'pt_title',
'pt_namespace',
'pt_create_perm',
'pt_expiry' ) );
538 foreach (
$res as $row ) {
539 $this->protections[$row->pt_namespace][$row->pt_title][] =
array(
541 'level' => $row->pt_create_perm,
548 $images = $others =
array();
549 foreach ( $this->everything
as $title ) {
551 $images[] =
$title->getDBkey();
557 if ( count( $others ) ) {
561 $this->
addTables(
array(
'page_restrictions',
'page',
'templatelinks' ) );
563 'page_title',
'page_namespace',
564 'tl_title',
'tl_namespace' ) );
566 $this->
addWhere(
'pr_page = page_id' );
567 $this->
addWhere(
'pr_page = tl_from' );
571 foreach (
$res as $row ) {
573 $this->protections[$row->tl_namespace][$row->tl_title][] =
array(
574 'type' => $row->pr_type,
575 'level' => $row->pr_level,
577 'source' =>
$source->getPrefixedText()
582 if ( count( $images ) ) {
585 $this->
addTables(
array(
'page_restrictions',
'page',
'imagelinks' ) );
587 'page_title',
'page_namespace',
'il_to' ) );
588 $this->
addWhere(
'pr_page = page_id' );
589 $this->
addWhere(
'pr_page = il_from' );
594 foreach (
$res as $row ) {
597 'type' => $row->pr_type,
598 'level' => $row->pr_level,
600 'source' =>
$source->getPrefixedText()
611 $getTitles = $this->talkids = $this->subjectids =
array();
614 foreach ( $this->everything
as $t ) {
616 if ( $this->fld_subjectid ) {
617 $getTitles[] =
$t->getSubjectPage();
619 } elseif ( $this->fld_talkid ) {
620 $getTitles[] =
$t->getTalkPage();
623 if ( !count( $getTitles ) ) {
627 $db = $this->
getDB();
634 $this->
addFields(
array(
'page_title',
'page_namespace',
'page_id' ) );
635 $this->
addWhere(
$lb->constructSet(
'page', $db ) );
637 foreach (
$res as $row ) {
640 intval( $row->page_id );
643 intval( $row->page_id );
649 $this->displaytitles =
array();
651 $pageIds = array_keys( $this->titles );
653 if ( !count( $pageIds ) ) {
661 $this->
addWhereFld(
'pp_propname',
'displaytitle' );
664 foreach (
$res as $row ) {
665 $this->displaytitles[$row->pp_page] = $row->pp_value;
676 if (
$user->isAnon() || count( $this->everything ) == 0
677 || !
$user->isAllowed(
'viewmywatchlist' )
682 $this->watched =
array();
683 $this->notificationtimestamps =
array();
684 $db = $this->
getDB();
691 $this->
addFieldsIf(
'wl_notificationtimestamp', $this->fld_notificationtimestamp );
693 $lb->constructSet(
'wl', $db ),
694 'wl_user' =>
$user->getID()
699 foreach (
$res as $row ) {
700 if ( $this->fld_watched ) {
701 $this->watched[$row->wl_namespace][$row->wl_title] =
true;
703 if ( $this->fld_notificationtimestamp ) {
704 $this->notificationtimestamps[$row->wl_namespace][$row->wl_title] =
705 $row->wl_notificationtimestamp;
714 global $wgUnwatchedPageThreshold;
716 if ( count( $this->everything ) == 0 ) {
721 $canUnwatchedpages =
$user->isAllowed(
'unwatchedpages' );
722 if ( !$canUnwatchedpages && !is_int( $wgUnwatchedPageThreshold ) ) {
726 $this->watchers =
array();
727 $this->showZeroWatchers = $canUnwatchedpages;
728 $db = $this->
getDB();
734 $this->
addFields(
array(
'wl_title',
'wl_namespace',
'count' =>
'COUNT(*)' ) );
736 $lb->constructSet(
'wl', $db )
738 $this->
addOption(
'GROUP BY',
array(
'wl_namespace',
'wl_title' ) );
739 if ( !$canUnwatchedpages ) {
740 $this->
addOption(
'HAVING',
"COUNT(*) >= $wgUnwatchedPageThreshold" );
745 foreach (
$res as $row ) {
746 $this->watchers[$row->wl_namespace][$row->wl_title] = (int)$row->count;
751 $publicProps =
array(
759 if ( !is_null(
$params[
'prop'] ) ) {
761 if ( !in_array( $prop, $publicProps ) ) {
766 if ( !is_null(
$params[
'token'] ) ) {
782 'watchers', #
private
783 'notificationtimestamp', #
private
786 'readable', #
private
804 'Which additional properties to get:',
805 ' protection - List the protection level of each page',
806 ' talkid - The page ID of the talk page for each non-talk page',
807 ' watched - List the watched status of each page',
808 ' watchers - The number of watchers, if allowed',
809 ' notificationtimestamp - The watchlist notification timestamp of each page',
810 ' subjectid - The page ID of the parent page for each talk page',
811 ' url - Gives a full URL to the page, and also an edit URL',
812 ' readable - Whether the user can read this page',
813 ' preload - Gives the text returned by EditFormPreloadText',
814 ' displaytitle - Gives the way the page title is actually displayed',
816 'token' =>
'Request a token to perform a data-modifying action on a page',
817 'continue' =>
'When more results are available, use this to continue',
825 'touched' =>
'timestamp',
826 'lastrevid' =>
'integer',
831 'length' =>
'integer',
832 'redirect' =>
'boolean',
834 'starttimestamp' =>
array(
838 'contentmodel' =>
'string',
841 'watched' =>
'boolean'
849 'notificationtimestamp' =>
array(
850 'notificationtimestamp' =>
array(
861 'subjectid' =>
array(
862 'subjectid' =>
array(
868 'fullurl' =>
'string',
869 'editurl' =>
'string'
872 'readable' =>
'boolean'
875 'preload' =>
'string'
877 'displaytitle' =>
array(
878 'displaytitle' =>
'string'
888 return 'Get basic page information such as namespace, title, last touched date, ...';
893 'api.php?action=query&prop=info&titles=Main%20Page',
894 'api.php?action=query&prop=info&inprop=protection&titles=Main%20Page'
899 return 'https://www.mediawiki.org/wiki/API:Properties#info_.2F_in';