(bug 29115) Add redirect target value on page info

Added inprop=redirecttarget

Refactored ApiPageSet::getRedirectTargets to having one method for
resolving redirect targets and calling that from prop=info.

Change-Id: Ia5fb9f25488880c2dd63e613c913a0864464d327
This commit is contained in:
umherirrender 2012-11-30 11:55:42 +01:00
parent 39351beea5
commit 0c6ba8c61d
3 changed files with 78 additions and 21 deletions

View file

@ -122,6 +122,7 @@ production.
* (bug 41042) Revert change to action=parse&page=... behavior when the page
does not exist.
* (bug 27202) Add timestamp sort to list=allimages.
* (bug 29115) Add redirect target value on page info.
=== Languages updated in 1.21 ===

View file

@ -624,10 +624,43 @@ class ApiPageSet extends ApiQueryBase {
* @return LinkBatch
*/
private function getRedirectTargets() {
$redirectTitles = $this->resolveIdsToRedirectTargets( array_keys( $this->mPendingRedirectIDs ), 'profileDB' );
$lb = new LinkBatch();
foreach( $this->mPendingRedirectIDs as $rdfrom => $from ) {
if( !isset( $redirectTitles[$rdfrom] ) ) {
continue;
}
$to = $redirectTitles[$rdfrom];
if ( $to && !isset( $this->mAllPages[$to->getNamespace()][$to->getText()] ) ) {
$lb->addObj( $to );
}
$this->mRedirectTitles[$from->getPrefixedText()] = $to;
}
return $lb;
}
/**
* Get the targets of redirects from the database
*
* Also creates entries in the redirect table for redirects that don't
* have one.
*
* @param $redirectIDs array The array of pageids to resolve
* @param $profileDB string if profileDBIn should called
* @return array id => redirect target as title
* @since 1.21
*/
public function resolveIdsToRedirectTargets( $redirectIDs, $profileDB = '' ) {
if( !$redirectIDs ) {
return array();
}
$db = $this->getDB();
$this->profileDBIn();
if( $profileDB ) {
$this->profileDBIn();
}
$res = $db->select(
'redirect',
array(
@ -636,37 +669,38 @@ class ApiPageSet extends ApiQueryBase {
'rd_fragment',
'rd_interwiki',
'rd_title'
), array( 'rd_from' => array_keys( $this->mPendingRedirectIDs ) ),
), array( 'rd_from' => $redirectIDs ),
__METHOD__
);
$this->profileDBOut();
foreach ( $res as $row ) {
$rdfrom = intval( $row->rd_from );
$from = $this->mPendingRedirectIDs[$rdfrom]->getPrefixedText();
$to = Title::makeTitle( $row->rd_namespace, $row->rd_title, $row->rd_fragment, $row->rd_interwiki );
unset( $this->mPendingRedirectIDs[$rdfrom] );
if ( !isset( $this->mAllPages[$row->rd_namespace][$row->rd_title] ) ) {
$lb->add( $row->rd_namespace, $row->rd_title );
}
$this->mRedirectTitles[$from] = $to;
if( $profileDB ) {
$this->profileDBOut();
}
if ( $this->mPendingRedirectIDs ) {
$redirectTitles = array();
foreach ( $res as $row ) {
$rdfrom = intval( $row->rd_from );
$to = Title::makeTitle( $row->rd_namespace, $row->rd_title, $row->rd_fragment, $row->rd_interwiki );
$redirectTitles[$rdfrom] = $to;
}
$unresolvedRedirectIDs = array_diff( $redirectIDs, array_keys( $redirectTitles ) );
if ( $unresolvedRedirectIDs ) {
// We found pages that aren't in the redirect table
// Add them
foreach ( $this->mPendingRedirectIDs as $id => $title ) {
$page = WikiPage::factory( $title );
foreach ( $unresolvedRedirectIDs as $id ) {
$page = WikiPage::newFromID( $id );
if ( !$page ) {
continue;
}
$rt = $page->insertRedirect();
if ( !$rt ) {
// What the hell. Let's just ignore this
continue;
}
$lb->addObj( $rt );
$this->mRedirectTitles[$title->getPrefixedText()] = $rt;
unset( $this->mPendingRedirectIDs[$id] );
$redirectTitles[$id] = $rt;
}
}
return $lb;
return $redirectTitles;
}
/**

View file

@ -34,12 +34,12 @@ class ApiQueryInfo extends ApiQueryBase {
private $fld_protection = false, $fld_talkid = false,
$fld_subjectid = false, $fld_url = false,
$fld_readable = false, $fld_watched = false, $fld_notificationtimestamp = false,
$fld_preload = false, $fld_displaytitle = false;
$fld_preload = false, $fld_displaytitle = false, $fld_redirecttarget = false;
private $params, $titles, $missing, $everything, $pageCounter;
private $pageRestrictions, $pageIsRedir, $pageIsNew, $pageTouched,
$pageLatest, $pageLength;
$pageLatest, $pageLength, $redirectTarget;
private $protections, $watched, $notificationtimestamps, $talkids, $subjectids, $displaytitles;
@ -255,6 +255,7 @@ class ApiQueryInfo extends ApiQueryBase {
$this->fld_readable = isset( $prop['readable'] );
$this->fld_preload = isset( $prop['preload'] );
$this->fld_displaytitle = isset( $prop['displaytitle'] );
$this->fld_redirecttarget = isset( $prop['redirecttarget'] );
}
$pageSet = $this->getPageSet();
@ -317,6 +318,10 @@ class ApiQueryInfo extends ApiQueryBase {
$this->getDisplayTitle();
}
if ( $this->fld_redirecttarget ) {
$this->redirectTarget = $pageSet->resolveIdsToRedirectTargets( array_keys( $this->pageIsRedir ) );
}
foreach ( $this->everything as $pageid => $title ) {
$pageInfo = $this->extractPageInfo( $pageid, $title );
$fit = $result->addValue( array(
@ -359,6 +364,13 @@ class ApiQueryInfo extends ApiQueryBase {
if ( $this->pageIsNew[$pageid] ) {
$pageInfo['new'] = '';
}
if ( $this->fld_redirecttarget && isset( $this->redirectTarget[$pageid] ) ) {
$targetTitle = $this->redirectTarget[$pageid];
$pageInfo['redirecttarget'] = $targetTitle->getPrefixedText();
if( $targetTitle->getFragment() !== '' ) {
$pageInfo['redirecttargetfragment'] = $targetTitle->getFragment();
}
}
}
if ( !is_null( $this->params['token'] ) ) {
@ -686,6 +698,7 @@ class ApiQueryInfo extends ApiQueryBase {
'url',
'preload',
'displaytitle',
'redirecttarget',
);
if ( !is_null( $params['prop'] ) ) {
foreach ( $params['prop'] as $prop ) {
@ -715,6 +728,7 @@ class ApiQueryInfo extends ApiQueryBase {
'readable', # private
'preload',
'displaytitle',
'redirecttarget',
// If you add more properties here, please consider whether they
// need to be added to getCacheMode()
) ),
@ -740,6 +754,7 @@ class ApiQueryInfo extends ApiQueryBase {
' readable - Whether the user can read this page',
' preload - Gives the text returned by EditFormPreloadText',
' displaytitle - Gives the way the page title is actually displayed',
' redirecttarget - Gives the redirect target, if this page is a redirect',
),
'token' => 'Request a token to perform a data-modifying action on a page',
'continue' => 'When more results are available, use this to continue',
@ -797,6 +812,13 @@ class ApiQueryInfo extends ApiQueryBase {
),
'displaytitle' => array(
'displaytitle' => 'string'
),
'redirecttarget' => array(
'redirecttarget' => 'string',
'redirecttargetfragment' => array(
ApiBase::PROP_TYPE => 'string',
ApiBase::PROP_NULLABLE => true
)
)
);