94 foreach ( $values
as $val ) {
95 if ( $val instanceof
Title ) {
98 } elseif (
$name !==
null ) {
99 $v = [
$name => $val ];
103 foreach ( $flags
as $flag ) {
119 $this->mDbSource = $dbSource;
121 $this->mDefaultNamespace = $defaultNamespace;
124 $this->mResolveRedirects = $this->mParams[
'redirects'];
125 $this->mConvertTitles = $this->mParams[
'converttitles'];
149 $generatorName = $this->mAllowGenerator ? $this->mParams[
'generator'] :
null;
150 if ( isset( $generatorName ) ) {
152 if ( !$dbSource instanceof
ApiQuery ) {
154 $dbSource = $this->
getMain()->getModuleManager()->getModule(
'query' );
156 $generator = $dbSource->getModuleManager()->getModule( $generatorName,
null,
true );
158 $this->
dieWithError( [
'apierror-badgenerator-unknown', $generatorName ],
'badgenerator' );
161 $this->
dieWithError( [
'apierror-badgenerator-notgenerator', $generatorName ],
'badgenerator' );
165 $tmpPageSet =
new ApiPageSet( $dbSource, self::DISABLE_GENERATORS );
172 $tmpPageSet->executeInternal( $isDryRun );
184 foreach (
$generator->extractRequestParams()
as $paramName => $param ) {
185 $main->markParamsUsed(
$generator->encodeParamName( $paramName ) );
195 if ( isset( $this->mParams[
'titles'] ) ) {
196 $dataSource =
'titles';
198 if ( isset( $this->mParams[
'pageids'] ) ) {
199 if ( isset( $dataSource ) ) {
202 'apierror-invalidparammix-cannotusewith',
209 $dataSource =
'pageids';
211 if ( isset( $this->mParams[
'revids'] ) ) {
212 if ( isset( $dataSource ) ) {
215 'apierror-invalidparammix-cannotusewith',
222 $dataSource =
'revids';
227 switch ( $dataSource ) {
235 if ( $this->mResolveRedirects ) {
236 $this->
addWarning(
'apiwarn-redirectsandrevids' );
238 $this->mResolveRedirects =
false;
266 if ( $this->mAllowGenerator && isset( $this->mParams[
'generator'] ) ) {
269 if ( isset( $this->mParams[
'titles'] ) ) {
272 if ( isset( $this->mParams[
'pageids'] ) ) {
275 if ( isset( $this->mParams[
'revids'] ) ) {
288 $this->mRequestedPageFields[$fieldName] =
null;
298 return $this->mRequestedPageFields[$fieldName];
311 'page_namespace' =>
null,
312 'page_title' =>
null,
316 if ( $this->mResolveRedirects ) {
317 $pageFlds[
'page_is_redirect'] =
null;
320 if ( $this->
getConfig()->
get(
'ContentHandlerUseDB' ) ) {
321 $pageFlds[
'page_content_model'] =
null;
324 if ( $this->
getConfig()->
get(
'PageLanguageUseDB' ) ) {
325 $pageFlds[
'page_lang'] =
null;
329 $pageFlds[$field] =
null;
332 $pageFlds = array_merge( $pageFlds, $this->mRequestedPageFields );
334 return array_keys( $pageFlds );
360 return count( $this->mTitles );
384 return count( $this->mGoodTitles );
458 'from' => strval( $titleStrFrom ),
459 'to' => $titleTo->getPrefixedText(),
461 if ( $titleTo->hasFragment() ) {
462 $r[
'tofragment'] = $titleTo->getFragment();
464 if ( $titleTo->isExternal() ) {
465 $r[
'tointerwiki'] = $titleTo->getInterwiki();
467 if ( isset( $this->mResolvedRedirectTitles[$titleStrFrom] ) ) {
468 $titleFrom = $this->mResolvedRedirectTitles[$titleStrFrom];
469 $ns = $titleFrom->getNamespace();
470 $dbkey = $titleFrom->getDBkey();
471 if ( isset( $this->mGeneratorData[$ns][$dbkey] ) ) {
472 $r = array_merge( $this->mGeneratorData[$ns][$dbkey], $r );
478 if ( !empty( $values ) &&
$result ) {
503 $contLang = MediaWikiServices::getInstance()->getContentLanguage();
505 $encode = $contLang->normalize( $rawTitleStr ) !== $rawTitleStr;
507 'fromencoded' => $encode,
508 'from' => $encode ? rawurlencode( $rawTitleStr ) : $rawTitleStr,
512 if ( !empty( $values ) &&
$result ) {
539 'from' => $rawTitleStr,
543 if ( !empty( $values ) &&
$result ) {
571 'title' => $rawTitleStr,
572 'iw' => $interwikiStr,
580 if ( !empty( $values ) &&
$result ) {
602 'special',
'missingIds',
'missingRevIds',
'missingTitles',
'interwikiTitles' ]
605 if ( in_array(
'invalidTitles', $invalidChecks ) ) {
608 if ( in_array(
'special', $invalidChecks ) ) {
612 if ( $title->isKnown() ) {
621 if ( in_array(
'missingIds', $invalidChecks ) ) {
624 if ( in_array(
'missingRevIds', $invalidChecks ) ) {
627 if ( in_array(
'missingTitles', $invalidChecks ) ) {
631 if ( $title->isKnown() ) {
640 if ( in_array(
'interwikiTitles', $invalidChecks ) ) {
692 if ( !empty( $values ) &&
$result ) {
760 $linkCache = MediaWikiServices::getInstance()->getLinkCache();
761 $linkCache->addGoodLinkObjFromRow(
$title, $row );
763 $pageId = intval( $row->page_id );
764 $this->mAllPages[$row->page_namespace][$row->page_title] = $pageId;
765 $this->mTitles[] =
$title;
767 if ( $this->mResolveRedirects && $row->page_is_redirect ==
'1' ) {
768 $this->mPendingRedirectIDs[$pageId] =
$title;
770 $this->mGoodPages[$row->page_namespace][$row->page_title] = $pageId;
771 $this->mGoodAndMissingPages[$row->page_namespace][$row->page_title] = $pageId;
772 $this->mGoodTitles[$pageId] =
$title;
775 foreach ( $this->mRequestedPageFields
as $fieldName => &$fieldValues ) {
776 $fieldValues[$pageId] = $row->$fieldName;
799 if ( $linkBatch->isEmpty() ) {
805 $db = $this->
getDB();
806 $set = $linkBatch->constructSet(
'page', $db );
828 $pageids = array_map(
'intval', $pageids );
829 $remaining = array_flip( $pageids );
834 if ( !empty( $pageids ) ) {
836 'page_id' => $pageids
838 $db = $this->
getDB();
862 if ( !is_null( $remaining ) && is_null( $processTitles ) ) {
863 ApiBase::dieDebug( __METHOD__,
'Missing $processTitles parameter when $remaining is provided' );
868 foreach (
$res as $row ) {
869 $pageId = intval( $row->page_id );
872 if ( isset( $remaining ) ) {
873 if ( $processTitles ) {
874 unset( $remaining[$row->page_namespace][$row->page_title] );
876 unset( $remaining[$pageId] );
885 $usernames[] = $row->page_title;
890 if ( isset( $remaining ) ) {
892 if ( $processTitles ) {
894 $linkCache = MediaWikiServices::getInstance()->getLinkCache();
895 foreach ( $remaining
as $ns => $dbkeys ) {
896 foreach ( array_keys( $dbkeys )
as $dbkey ) {
898 $linkCache->addBadLinkObj(
$title );
903 $this->mFakePageId--;
904 $this->mTitles[] =
$title;
908 $usernames[] = $dbkey;
914 if ( !$this->mMissingPageIDs ) {
915 $this->mMissingPageIDs = array_keys( $remaining );
917 $this->mMissingPageIDs = array_merge( $this->mMissingPageIDs, array_keys( $remaining ) );
923 $genderCache = MediaWikiServices::getInstance()->getGenderCache();
924 $genderCache->doQuery( $usernames, __METHOD__ );
937 $revids = array_map(
'intval', $revids );
938 $db = $this->
getDB();
940 $remaining = array_flip( $revids );
944 if ( !empty( $revids ) ) {
945 $tables = [
'revision',
'page' ];
946 $fields = [
'rev_id',
'rev_page' ];
947 $where = [
'rev_id' => $revids,
'rev_page = page_id' ];
950 $res = $db->select(
$tables, $fields, $where, __METHOD__ );
951 foreach (
$res as $row ) {
952 $revid = intval( $row->rev_id );
953 $pageid = intval( $row->rev_page );
954 $this->mGoodRevIDs[$revid] = $pageid;
955 $this->mLiveRevIDs[$revid] = $pageid;
956 $pageids[$pageid] =
'';
957 unset( $remaining[$revid] );
961 $this->mMissingRevIDs = array_keys( $remaining );
969 if ( !empty( $this->mMissingRevIDs ) && $this->
getUser()->isAllowed(
'deletedhistory' ) ) {
970 $remaining = array_flip( $this->mMissingRevIDs );
972 $fields = [
'ar_rev_id',
'ar_namespace',
'ar_title' ];
975 $res = $db->select(
$tables, $fields, $where, __METHOD__ );
977 foreach (
$res as $row ) {
978 $revid = intval( $row->ar_rev_id );
980 unset( $remaining[$revid] );
986 $ns =
$title->getNamespace();
987 $dbkey =
$title->getDBkey();
990 if ( !isset( $this->mAllPages[$ns][$dbkey] ) &&
991 isset( $this->mConvertedTitles[
$title->getPrefixedText()] )
994 $ns =
$title->getNamespace();
995 $dbkey =
$title->getDBkey();
998 if ( isset( $this->mAllPages[$ns][$dbkey] ) ) {
999 $this->mGoodRevIDs[$revid] = $this->mAllPages[$ns][$dbkey];
1000 $this->mDeletedRevIDs[$revid] = $this->mAllPages[$ns][$dbkey];
1002 $remaining[$revid] =
true;
1006 $this->mMissingRevIDs = array_keys( $remaining );
1016 if ( $this->mResolveRedirects ) {
1017 $db = $this->
getDB();
1022 while ( $this->mPendingRedirectIDs || $this->mPendingRedirectSpecialPages ) {
1027 if ( $linkBatch->isEmpty() ) {
1031 $set = $linkBatch->constructSet(
'page', $db );
1032 if ( $set ===
false ) {
1037 $res = $db->select(
'page', $pageFlds, $set, __METHOD__ );
1053 $titlesToResolve = [];
1054 $db = $this->
getDB();
1056 if ( $this->mPendingRedirectIDs ) {
1065 ], [
'rd_from' => array_keys( $this->mPendingRedirectIDs ) ],
1068 foreach (
$res as $row ) {
1069 $rdfrom = intval( $row->rd_from );
1070 $from = $this->mPendingRedirectIDs[$rdfrom]->getPrefixedText();
1077 $this->mResolvedRedirectTitles[$from] = $this->mPendingRedirectIDs[$rdfrom];
1078 unset( $this->mPendingRedirectIDs[$rdfrom] );
1079 if ( $to->isExternal() ) {
1080 $this->mInterwikiTitles[$to->getPrefixedText()] = $to->getInterwiki();
1081 } elseif ( !isset( $this->mAllPages[$to->getNamespace()][$to->getDBkey()] ) ) {
1082 $titlesToResolve[] = $to;
1084 $this->mRedirectTitles[$from] = $to;
1087 if ( $this->mPendingRedirectIDs ) {
1090 foreach ( $this->mPendingRedirectIDs
as $id =>
$title ) {
1092 $rt = $page->insertRedirect();
1097 if ( $rt->isExternal() ) {
1098 $this->mInterwikiTitles[$rt->getPrefixedText()] = $rt->getInterwiki();
1099 } elseif ( !isset( $this->mAllPages[$rt->getNamespace()][$rt->getDBkey()] ) ) {
1100 $titlesToResolve[] = $rt;
1102 $from =
$title->getPrefixedText();
1103 $this->mResolvedRedirectTitles[$from] =
$title;
1104 $this->mRedirectTitles[$from] = $rt;
1105 unset( $this->mPendingRedirectIDs[$id] );
1110 if ( $this->mPendingRedirectSpecialPages ) {
1111 foreach ( $this->mPendingRedirectSpecialPages
as $key =>
list( $from, $to ) ) {
1112 $fromKey = $from->getPrefixedText();
1113 $this->mResolvedRedirectTitles[$fromKey] = $from;
1114 $this->mRedirectTitles[$fromKey] = $to;
1115 if ( $to->isExternal() ) {
1116 $this->mInterwikiTitles[$to->getPrefixedText()] = $to->getInterwiki();
1117 } elseif ( !isset( $this->mAllPages[$to->getNamespace()][$to->getDBkey()] ) ) {
1118 $titlesToResolve[] = $to;
1121 $this->mPendingRedirectSpecialPages = [];
1125 $this->mCacheMode =
'private';
1160 $services = MediaWikiServices::getInstance();
1161 $contLang =
$services->getContentLanguage();
1164 if ( is_string(
$title ) ) {
1169 if ( !isset( $this->mAllPages[0][
$title] ) ) {
1173 'invalidreason' => $this->
getErrorFormatter()->formatException( $ex, [
'bc' =>
true ] ),
1175 $this->mFakePageId--;
1182 $unconvertedTitle = $titleObj->getPrefixedText();
1183 $titleWasConverted =
false;
1184 if ( $titleObj->isExternal() ) {
1186 $this->mInterwikiTitles[$unconvertedTitle] = $titleObj->getInterwiki();
1190 $this->mConvertTitles && $contLang->hasVariants() && !$titleObj->exists()
1194 $titleText = is_string(
$title ) ?
$title : $titleObj->getPrefixedText();
1195 $contLang->findVariantLink( $titleText, $titleObj );
1196 $titleWasConverted = $unconvertedTitle !== $titleObj->getPrefixedText();
1199 if ( $titleObj->getNamespace() < 0 ) {
1201 $titleObj = $titleObj->fixSpecialName();
1202 $ns = $titleObj->getNamespace();
1203 $dbkey = $titleObj->getDBkey();
1204 if ( !isset( $this->mAllSpecials[$ns][$dbkey] ) ) {
1207 if ( $ns ===
NS_SPECIAL && $this->mResolveRedirects ) {
1208 $spFactory =
$services->getSpecialPageFactory();
1209 $special = $spFactory->getPage( $dbkey );
1217 list( , $subpage ) = $spFactory->resolveAlias( $dbkey );
1218 $target = $special->getRedirect( $subpage );
1222 $this->mPendingRedirectSpecialPages[$dbkey] = [ $titleObj, $target ];
1225 $this->mFakePageId--;
1230 $linkBatch->addObj( $titleObj );
1239 if ( $titleWasConverted ) {
1240 $this->mConvertedTitles[$unconvertedTitle] = $titleObj->getPrefixedText();
1242 if ( is_string(
$title ) &&
$title !== $unconvertedTitle ) {
1243 $this->mNormalizedTitles[
$title] = $unconvertedTitle;
1245 } elseif ( is_string(
$title ) &&
$title !== $titleObj->getPrefixedText() ) {
1246 $this->mNormalizedTitles[
$title] = $titleObj->getPrefixedText();
1251 $usernames[] = $titleObj->getText();
1255 $genderCache =
$services->getGenderCache();
1256 $genderCache->doQuery( $usernames, __METHOD__ );
1277 $ns =
$title->getNamespace();
1278 $dbkey =
$title->getDBkey();
1279 $this->mGeneratorData[$ns][$dbkey] = $data;
1302 $this->mRedirectMergePolicy = $callable;
1328 if ( $data ===
null ) {
1334 if ( !isset( $data[$key] ) ) {
1339 $data = &$data[$key];
1342 foreach ( $this->mGeneratorData
as $ns => $dbkeys ) {
1345 foreach ( $this->mSpecialTitles
as $id =>
$title ) {
1346 $pages[
$title->getDBkey()] = $id;
1349 if ( !isset( $this->mAllPages[$ns] ) ) {
1353 $pages = $this->mAllPages[$ns];
1355 foreach ( $dbkeys
as $dbkey => $genData ) {
1356 if ( !isset( $pages[$dbkey] ) ) {
1360 $pageId = $pages[$dbkey];
1361 if ( !isset( $data[$pageId] ) ) {
1367 $path2 = array_merge(
$path, [ $pageId ] );
1368 foreach ( $genData
as $key =>
$value ) {
1374 $data[$pageId] = array_merge( $data[$pageId], $genData );
1380 if ( $this->mRedirectMergePolicy ) {
1381 foreach ( $this->mResolvedRedirectTitles
as $titleFrom ) {
1383 while ( isset( $this->mRedirectTitles[$dest->getPrefixedText()] ) ) {
1384 $dest = $this->mRedirectTitles[$dest->getPrefixedText()];
1386 $fromNs = $titleFrom->getNamespace();
1387 $fromDBkey = $titleFrom->getDBkey();
1388 $toPageId = $dest->getArticleID();
1389 if ( isset( $data[$toPageId] ) &&
1390 isset( $this->mGeneratorData[$fromNs][$fromDBkey] )
1394 $data[$toPageId] = call_user_func(
1395 $this->mRedirectMergePolicy,
1397 $this->mGeneratorData[$fromNs][$fromDBkey]
1416 return $this->mDbSource->getDB();
1429 foreach ( $array
as $i => $int ) {
1431 unset( $array[$i] );
1462 ?
'api-pageset-param-redirects-generator'
1463 :
'api-pageset-param-redirects-nogenerator',
1465 'converttitles' => [
1468 'api-pageset-param-converttitles',
1469 [ Message::listParam( LanguageConverter::$languagesWithVariants,
'text' ) ],
1474 if ( !$this->mAllowGenerator ) {
1475 unset(
$result[
'generator'] );
1485 parent::handleParamNormalization( $paramName,
$value, $rawValue );
1487 if ( $paramName ===
'titles' ) {
1493 for ( $i = 0; $i < $l; $i++ ) {
1494 if (
$value[$i] !== $rawValue[$i] ) {
1495 $this->mNormalizedTitles[$rawValue[$i]] =
$value[$i];
1508 if ( self::$generators ===
null ) {
1513 $query = $this->
getMain()->getModuleManager()->getModule(
'query' );
1516 $prefix =
$query->getModulePath() .
'+';
1517 $mgr =
$query->getModuleManager();
1518 foreach ( $mgr->getNamesWithClasses()
as $name => $class ) {
1524 self::$generators = $gens;