Support ApiPageSet in ApiWatch
Add support for ApiPageSet capabilities in ApiWatch to support batch operation on titles, pageids etc. The old 'title' parameter (for a single page) is still supported to keep backwards compatibility. Moved a function from ApiPurge to ApiPageSet: getInvalidTitlesAndRevisions() gathers warnings about invalid/missing titles/ids in the requested page set. Split from If993f6e8. Change-Id: I820dcb64d469616b10741df013911197cc5bde29
This commit is contained in:
parent
9d0b230b65
commit
75e28dc018
6 changed files with 163 additions and 55 deletions
1
CREDITS
1
CREDITS
|
|
@ -129,6 +129,7 @@ following names for their contribution to the product.
|
|||
* Ebrahim Byagowi
|
||||
* Edward Z. Yang
|
||||
* Elvis Stansvik
|
||||
* Eranroz
|
||||
* Erwin Dokter
|
||||
* Federico Leva
|
||||
* FunPika
|
||||
|
|
|
|||
|
|
@ -150,6 +150,8 @@ production.
|
|||
list=usercontribs.
|
||||
* list=watchlist now uses the querying user's rights rather than the wlowner's
|
||||
rights when checking whether wlprop=patrol is allowed.
|
||||
* (bug 32151) ApiWatch now has pageset capabilities (titles/pageids/generators).
|
||||
Title parameter is now deprecated.
|
||||
|
||||
=== Languages updated in 1.23 ===
|
||||
|
||||
|
|
|
|||
|
|
@ -1362,13 +1362,13 @@ abstract class ApiBase extends ContextSource {
|
|||
}
|
||||
|
||||
/**
|
||||
* Throw a UsageException based on the errors in the Status object.
|
||||
* Get error (as code, string) from a Status object.
|
||||
*
|
||||
* @since 1.22
|
||||
* @since 1.23
|
||||
* @param Status $status Status object
|
||||
* @throws MWException
|
||||
* @return array of code and error string
|
||||
*/
|
||||
public function dieStatus( $status ) {
|
||||
public function getErrorFromStatus( $status ) {
|
||||
if ( $status->isGood() ) {
|
||||
throw new MWException( 'Successful status passed to ApiBase::dieStatus' );
|
||||
}
|
||||
|
|
@ -1396,7 +1396,20 @@ abstract class ApiBase extends ContextSource {
|
|||
// Translate message to code, for backwards compatability
|
||||
$code = ApiBase::$messageMap[$code]['code'];
|
||||
}
|
||||
$this->dieUsage( $msg->inLanguage( 'en' )->useDatabase( false )->plain(), $code );
|
||||
return array( $code, $msg->inLanguage( 'en' )->useDatabase( false )->plain() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw a UsageException based on the errors in the Status object.
|
||||
*
|
||||
* @since 1.22
|
||||
* @param Status $status Status object
|
||||
* @throws MWException
|
||||
*/
|
||||
public function dieStatus( $status ) {
|
||||
|
||||
list( $code, $msg ) = $this->getErrorFromStatus( $status );
|
||||
$this->dieUsage( $msg, $code );
|
||||
}
|
||||
|
||||
// @codingStandardsIgnoreStart Allow long lines. Cannot split these.
|
||||
|
|
|
|||
|
|
@ -74,6 +74,30 @@ class ApiPageSet extends ApiBase {
|
|||
*/
|
||||
private $mDefaultNamespace = NS_MAIN;
|
||||
|
||||
/**
|
||||
* Add all items from $values into the result
|
||||
* @param array $result output
|
||||
* @param array $values values to add
|
||||
* @param string $flag the name of the boolean flag to mark this element
|
||||
* @param string $name if given, name of the value
|
||||
*/
|
||||
private static function addValues( array &$result, $values, $flag = null, $name = null ) {
|
||||
foreach ( $values as $val ) {
|
||||
if ( $val instanceof Title ) {
|
||||
$v = array();
|
||||
ApiQueryBase::addTitleInfo( $v, $val );
|
||||
} elseif ( $name !== null ) {
|
||||
$v = array( $name => $val );
|
||||
} else {
|
||||
$v = $val;
|
||||
}
|
||||
if ( $flag !== null ) {
|
||||
$v[$flag] = '';
|
||||
}
|
||||
$result[] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param $dbSource ApiBase Module implementing getDB().
|
||||
|
|
@ -498,6 +522,43 @@ class ApiPageSet extends ApiBase {
|
|||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of invalid/special/missing titles.
|
||||
*
|
||||
* @param $invalidChecks List of types of invalid titles to include.
|
||||
* Recognized values are:
|
||||
* - invalidTitles: Titles from $this->getInvalidTitles()
|
||||
* - special: Titles from $this->getSpecialTitles()
|
||||
* - missingIds: ids from $this->getMissingPageIDs()
|
||||
* - missingRevIds: ids from $this->getMissingRevisionIDs()
|
||||
* - missingTitles: Titles from $this->getMissingTitles()
|
||||
* - interwikiTitles: Titles from $this->getInterwikiTitlesAsResult()
|
||||
* @return array Array suitable for inclusion in the response
|
||||
* @since 1.23
|
||||
*/
|
||||
public function getInvalidTitlesAndRevisions( $invalidChecks = array( 'invalidTitles', 'special', 'missingIds', 'missingRevIds', 'missingTitles', 'interwikiTitles' ) ) {
|
||||
$result = array();
|
||||
if ( in_array( "invalidTitles", $invalidChecks ) ) {
|
||||
self::addValues( $result, $this->getInvalidTitles(), 'invalid', 'title' );
|
||||
}
|
||||
if ( in_array( "special", $invalidChecks ) ) {
|
||||
self::addValues( $result, $this->getSpecialTitles(), 'special', 'title' );
|
||||
}
|
||||
if ( in_array( "missingIds", $invalidChecks ) ) {
|
||||
self::addValues( $result, $this->getMissingPageIDs(), 'missing', 'pageid' );
|
||||
}
|
||||
if ( in_array( "missingRevIds", $invalidChecks ) ) {
|
||||
self::addValues( $result, $this->getMissingRevisionIDs(), 'missing', 'revid' );
|
||||
}
|
||||
if ( in_array( "missingTitles", $invalidChecks ) ) {
|
||||
self::addValues( $result, $this->getMissingTitles(), 'missing' );
|
||||
}
|
||||
if ( in_array( "interwikiTitles", $invalidChecks ) ) {
|
||||
self::addValues( $result, $this->getInterwikiTitlesAsResult() );
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of revision IDs (requested with the revids= parameter)
|
||||
* @return array revID (int) => pageID (int)
|
||||
|
|
|
|||
|
|
@ -32,30 +32,6 @@
|
|||
class ApiPurge extends ApiBase {
|
||||
private $mPageSet;
|
||||
|
||||
/**
|
||||
* Add all items from $values into the result
|
||||
* @param array $result output
|
||||
* @param array $values values to add
|
||||
* @param string $flag the name of the boolean flag to mark this element
|
||||
* @param string $name if given, name of the value
|
||||
*/
|
||||
private static function addValues( array &$result, $values, $flag = null, $name = null ) {
|
||||
foreach ( $values as $val ) {
|
||||
if ( $val instanceof Title ) {
|
||||
$v = array();
|
||||
ApiQueryBase::addTitleInfo( $v, $val );
|
||||
} elseif ( $name !== null ) {
|
||||
$v = array( $name => $val );
|
||||
} else {
|
||||
$v = $val;
|
||||
}
|
||||
if ( $flag !== null ) {
|
||||
$v[$flag] = '';
|
||||
}
|
||||
$result[] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Purges the cache of a page
|
||||
*/
|
||||
|
|
@ -67,13 +43,7 @@ class ApiPurge extends ApiBase {
|
|||
$pageSet = $this->getPageSet();
|
||||
$pageSet->execute();
|
||||
|
||||
$result = array();
|
||||
self::addValues( $result, $pageSet->getInvalidTitles(), 'invalid', 'title' );
|
||||
self::addValues( $result, $pageSet->getSpecialTitles(), 'special', 'title' );
|
||||
self::addValues( $result, $pageSet->getMissingPageIDs(), 'missing', 'pageid' );
|
||||
self::addValues( $result, $pageSet->getMissingRevisionIDs(), 'missing', 'revid' );
|
||||
self::addValues( $result, $pageSet->getMissingTitles(), 'missing' );
|
||||
self::addValues( $result, $pageSet->getInterwikiTitlesAsResult() );
|
||||
$result = $pageSet->getInvalidTitlesAndRevisions();
|
||||
|
||||
foreach ( $pageSet->getGoodTitles() as $title ) {
|
||||
$r = array();
|
||||
|
|
|
|||
|
|
@ -30,21 +30,57 @@
|
|||
* @ingroup API
|
||||
*/
|
||||
class ApiWatch extends ApiBase {
|
||||
private $mPageSet = null;
|
||||
|
||||
public function execute() {
|
||||
$user = $this->getUser();
|
||||
if ( !$user->isLoggedIn() ) {
|
||||
$this->dieUsage( 'You must be logged-in to have a watchlist', 'notloggedin' );
|
||||
}
|
||||
|
||||
if ( !$user->isAllowed( 'editmywatchlist' ) ) {
|
||||
$this->dieUsage( 'You don\'t have permission to edit your watchlist', 'permissiondenied' );
|
||||
}
|
||||
|
||||
$params = $this->extractRequestParams();
|
||||
$title = Title::newFromText( $params['title'] );
|
||||
$pageSet = $this->getPageSet();
|
||||
// by default we use pageset to extract the page to work on.
|
||||
// title is still supported for backward compatibility
|
||||
if ( !isset( $params['title'] ) ) {
|
||||
$pageSet->execute();
|
||||
$res = $pageSet->getInvalidTitlesAndRevisions( array( 'invalidTitles', 'special', 'missingIds', 'missingRevIds', 'interwikiTitles' ) );
|
||||
foreach ( $pageSet->getMissingTitles() as $title ) {
|
||||
$r = $this->watchTitle( $title, $user, $params );
|
||||
$r['missing'] = 1;
|
||||
$res[] = $r;
|
||||
}
|
||||
foreach ( $pageSet->getGoodTitles() as $title ) {
|
||||
$r = $this->watchTitle( $title, $user, $params );
|
||||
$res[] = $r;
|
||||
}
|
||||
$this->getResult()->setIndexedTagName( $res, 'w' );
|
||||
} else {
|
||||
// dont allow use of old title parameter with new pageset parameters.
|
||||
$extraParams = array_keys( array_filter( $pageSet->extractRequestParams(), function ( $x ) {
|
||||
return $x !== null && $x !== false;
|
||||
} ) );
|
||||
if ( $extraParams ) {
|
||||
$p = $this->getModulePrefix();
|
||||
$this->dieUsage( "The parameter {$p}title can not be used with ". implode( ", ", $extraParams ), 'invalidparammix' );
|
||||
}
|
||||
|
||||
if ( !$title || !$title->isWatchable() ) {
|
||||
$this->dieUsageMsg( array( 'invalidtitle', $params['title'] ) );
|
||||
$title = Title::newFromText( $params['title'] );
|
||||
if ( !$title || !$title->isWatchable() ) {
|
||||
$this->dieUsageMsg( array( 'invalidtitle', $params['title'] ) );
|
||||
}
|
||||
$res = $this->watchTitle( $title, $user, $params, true );
|
||||
}
|
||||
$this->getResult()->addValue( null, $this->getModuleName(), $res );
|
||||
}
|
||||
|
||||
private function watchTitle( Title $title, User $user, array $params, $compatibilityMode = false ) {
|
||||
if ( !$title->isWatchable() ) {
|
||||
return array( 'title' => $title->getPrefixedText(), 'watchable' => 0 );
|
||||
}
|
||||
|
||||
$res = array( 'title' => $title->getPrefixedText() );
|
||||
|
|
@ -61,25 +97,45 @@ class ApiWatch extends ApiBase {
|
|||
}
|
||||
|
||||
if ( $params['unwatch'] ) {
|
||||
$res['unwatched'] = '';
|
||||
$res['message'] = $this->msg( 'removedwatchtext', $title->getPrefixedText() )
|
||||
->title( $title )->parseAsBlock();
|
||||
$status = UnwatchAction::doUnwatch( $title, $user );
|
||||
if ( $status->isOK() ) {
|
||||
$res['unwatched'] = '';
|
||||
$res['message'] = $this->msg( 'removedwatchtext', $title->getPrefixedText() )
|
||||
->title( $title )->parseAsBlock();
|
||||
}
|
||||
} else {
|
||||
$res['watched'] = '';
|
||||
$res['message'] = $this->msg( 'addedwatchtext', $title->getPrefixedText() )
|
||||
->title( $title )->parseAsBlock();
|
||||
$status = WatchAction::doWatch( $title, $user );
|
||||
if ( $status->isOK() ) {
|
||||
$res['watched'] = '';
|
||||
$res['message'] = $this->msg( 'addedwatchtext', $title->getPrefixedText() )
|
||||
->title( $title )->parseAsBlock();
|
||||
}
|
||||
}
|
||||
|
||||
if ( !is_null( $oldLang ) ) {
|
||||
$this->getContext()->setLanguage( $oldLang ); // Reset language to $oldLang
|
||||
}
|
||||
|
||||
|
||||
if ( !$status->isOK() ) {
|
||||
$this->dieStatus( $status );
|
||||
if ( $compatibilityMode ) {
|
||||
$this->dieStatus( $status );
|
||||
}
|
||||
$res['error'] = $this->getErrorFromStatus( $status );
|
||||
}
|
||||
$this->getResult()->addValue( null, $this->getModuleName(), $res );
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a cached instance of an ApiPageSet object
|
||||
* @return ApiPageSet
|
||||
*/
|
||||
private function getPageSet() {
|
||||
if ( $this->mPageSet === null ) {
|
||||
$this->mPageSet = new ApiPageSet( $this );
|
||||
}
|
||||
return $this->mPageSet;
|
||||
}
|
||||
|
||||
public function mustBePosted() {
|
||||
|
|
@ -98,11 +154,11 @@ class ApiWatch extends ApiBase {
|
|||
return 'watch';
|
||||
}
|
||||
|
||||
public function getAllowedParams() {
|
||||
return array(
|
||||
public function getAllowedParams( $flags = 0 ) {
|
||||
$result = array(
|
||||
'title' => array(
|
||||
ApiBase::PARAM_TYPE => 'string',
|
||||
ApiBase::PARAM_REQUIRED => true
|
||||
ApiBase::PARAM_DEPRECATED => true
|
||||
),
|
||||
'unwatch' => false,
|
||||
'uselang' => null,
|
||||
|
|
@ -111,11 +167,16 @@ class ApiWatch extends ApiBase {
|
|||
ApiBase::PARAM_REQUIRED => true
|
||||
),
|
||||
);
|
||||
if ( $flags ) {
|
||||
$result += $this->getPageSet()->getFinalParams( $flags );
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function getParamDescription() {
|
||||
return array(
|
||||
'title' => 'The page to (un)watch',
|
||||
$psModule = $this->getPageSet();
|
||||
return $psModule->getParamDescription() + array(
|
||||
'title' => 'The page to (un)watch. use titles instead',
|
||||
'unwatch' => 'If set the page will be unwatched rather than watched',
|
||||
'uselang' => 'Language to show the message in',
|
||||
'token' => 'A token previously acquired via prop=info',
|
||||
|
|
@ -134,7 +195,7 @@ class ApiWatch extends ApiBase {
|
|||
}
|
||||
|
||||
public function getDescription() {
|
||||
return 'Add or remove a page from/to the current user\'s watchlist';
|
||||
return 'Add or remove pages from/to the current user\'s watchlist';
|
||||
}
|
||||
|
||||
public function getPossibleErrors() {
|
||||
|
|
@ -147,8 +208,8 @@ class ApiWatch extends ApiBase {
|
|||
|
||||
public function getExamples() {
|
||||
return array(
|
||||
'api.php?action=watch&title=Main_Page' => 'Watch the page "Main Page"',
|
||||
'api.php?action=watch&title=Main_Page&unwatch=' => 'Unwatch the page "Main Page"',
|
||||
'api.php?action=watch&titles=Main_Page' => 'Watch the page "Main Page"',
|
||||
'api.php?action=watch&titles=Main_Page&unwatch=' => 'Unwatch the page "Main Page"',
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue