'ApiOpenSearch' => 'includes/api/ApiOpenSearch.php',
'ApiPageSet' => 'includes/api/ApiPageSet.php',
'ApiParse' => 'includes/api/ApiParse.php',
+ 'ApiQuery' => 'includes/api/ApiQuery.php',
+ 'ApiQueryAllpages' => 'includes/api/ApiQueryAllpages.php',
+ 'ApiQueryAllLinks' => 'includes/api/ApiQueryAllLinks.php',
+ 'ApiQueryAllUsers' => 'includes/api/ApiQueryAllUsers.php',
+ 'ApiQueryBase' => 'includes/api/ApiQueryBase.php',
+ 'ApiQueryGeneratorBase' => 'includes/api/ApiQueryBase.php',
+ 'ApiQueryBacklinks' => 'includes/api/ApiQueryBacklinks.php',
+ 'ApiQueryCategories' => 'includes/api/ApiQueryCategories.php',
+ 'ApiQueryCategoryMembers' => 'includes/api/ApiQueryCategoryMembers.php',
+ 'ApiQueryContributions' => 'includes/api/ApiQueryUserContributions.php',
+ 'ApiQueryExternalLinks' => 'includes/api/ApiQueryExternalLinks.php',
+ 'ApiQueryExtLinksUsage' => 'includes/api/ApiQueryExtLinksUsage.php',
+ 'ApiQueryImages' => 'includes/api/ApiQueryImages.php',
+ 'ApiQueryImageInfo' => 'includes/api/ApiQueryImageInfo.php',
+ 'ApiQueryInfo' => 'includes/api/ApiQueryInfo.php',
+ 'ApiQueryLangLinks' => 'includes/api/ApiQueryLangLinks.php',
+ 'ApiQueryLinks' => 'includes/api/ApiQueryLinks.php',
+ 'ApiQueryLogEvents' => 'includes/api/ApiQueryLogEvents.php',
+ 'ApiQueryRecentChanges'=> 'includes/api/ApiQueryRecentChanges.php',
+ 'ApiQueryRevisions' => 'includes/api/ApiQueryRevisions.php',
+ 'ApiQuerySearch' => 'includes/api/ApiQuerySearch.php',
+ 'ApiQueryAllmessages' => 'includes/api/ApiQueryAllmessages.php',
+ 'ApiQuerySiteinfo' => 'includes/api/ApiQuerySiteinfo.php',
+ 'ApiQueryUserInfo' => 'includes/api/ApiQueryUserInfo.php',
+ 'ApiQueryWatchlist' => 'includes/api/ApiQueryWatchlist.php',
'ApiRender' => 'includes/api/ApiRender.php',
'ApiResult' => 'includes/api/ApiResult.php',
- # Query API
- 'ApiQuery' => 'includes/api/query/ApiQuery.php',
- 'ApiQueryAllpages' => 'includes/api/query/ApiQueryAllpages.php',
- 'ApiQueryAllLinks' => 'includes/api/query/ApiQueryAllLinks.php',
- 'ApiQueryAllUsers' => 'includes/api/query/ApiQueryAllUsers.php',
- 'ApiQueryBase' => 'includes/api/query/ApiQueryBase.php',
- 'ApiQueryGeneratorBase' => 'includes/api/query/ApiQueryBase.php',
- 'ApiQueryBlocks' => 'includes/api/query/ApiQueryBlocks.php',
- 'ApiQueryBacklinks' => 'includes/api/query/ApiQueryBacklinks.php',
- 'ApiQueryCategories' => 'includes/api/query/ApiQueryCategories.php',
- 'ApiQueryCategoryMembers' => 'includes/api/query/ApiQueryCategoryMembers.php',
- 'ApiQueryContributions' => 'includes/api/query/ApiQueryUserContributions.php',
- 'ApiQueryDeletedrevs' => 'includes/api/query/ApiQueryDeletedrevs.php',
- 'ApiQueryExternalLinks' => 'includes/api/query/ApiQueryExternalLinks.php',
- 'ApiQueryExtLinksUsage' => 'includes/api/query/ApiQueryExtLinksUsage.php',
- 'ApiQueryImages' => 'includes/api/query/ApiQueryImages.php',
- 'ApiQueryImageInfo' => 'includes/api/query/ApiQueryImageInfo.php',
- 'ApiQueryInfo' => 'includes/api/query/ApiQueryInfo.php',
- 'ApiQueryLangLinks' => 'includes/api/query/ApiQueryLangLinks.php',
- 'ApiQueryLinks' => 'includes/api/query/ApiQueryLinks.php',
- 'ApiQueryLogEvents' => 'includes/api/query/ApiQueryLogEvents.php',
- 'ApiQueryRecentChanges'=> 'includes/api/query/ApiQueryRecentChanges.php',
- 'ApiQueryRevisions' => 'includes/api/query/ApiQueryRevisions.php',
- 'ApiQuerySearch' => 'includes/api/query/ApiQuerySearch.php',
- 'ApiQueryAllmessages' => 'includes/api/query/ApiQueryAllmessages.php',
- 'ApiQuerySiteinfo' => 'includes/api/query/ApiQuerySiteinfo.php',
- 'ApiQueryUserInfo' => 'includes/api/query/ApiQueryUserInfo.php',
- 'ApiQueryWatchlist' => 'includes/api/query/ApiQueryWatchlist.php',
-
- # API edit functions
- 'ApiBlock' => 'includes/api/edit/ApiBlock.php',
- 'ApiChangeRights' => 'includes/api/edit/ApiChangeRights.php',
- 'ApiDelete' => 'includes/api/edit/ApiDelete.php',
- 'ApiMove' => 'includes/api/edit/ApiMove.php',
- 'ApiProtect' => 'includes/api/edit/ApiProtect.php',
- 'ApiRollback' => 'includes/api/edit/ApiRollback.php',
- 'ApiUnblock' => 'includes/api/edit/ApiUnblock.php',
- 'ApiUndelete' => 'includes/api/edit/ApiUndelete.php'
+ # apiedit branch
+ 'ApiBlock' => 'includes/api/ApiBlock.php',
+ 'ApiChangeRights' => 'includes/api/ApiChangeRights.php',
+ 'ApiDelete' => 'includes/api/ApiDelete.php',
+ 'ApiMove' => 'includes/api/ApiMove.php',
+ 'ApiProtect' => 'includes/api/ApiProtect.php',
+ 'ApiQueryBlocks' => 'includes/api/ApiQueryBlocks.php',
+ 'ApiQueryDeletedrevs' => 'includes/api/ApiQueryDeletedrevs.php',
+ 'ApiRollback' => 'includes/api/ApiRollback.php',
+ 'ApiUnblock' => 'includes/api/ApiUnblock.php',
+ 'ApiUndelete' => 'includes/api/ApiUndelete.php'
);
wfProfileIn( __METHOD__ );
--- /dev/null
+<?php
+
+/*
+ * Created on Sep 4, 2007
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ("ApiBase.php");
+}
+
+/**
+ * @addtogroup API
+ */
+class ApiBlock extends ApiBase {
+
+ public function __construct($main, $action) {
+ parent :: __construct($main, $action);
+ }
+
+ public function execute() {
+ global $wgUser;
+ $this->getMain()->requestWriteMode();
+ $params = $this->extractRequestParams();
+
+ if($params['gettoken'])
+ {
+ $res['blocktoken'] = $wgUser->editToken();
+ $this->getResult()->addValue(null, $this->getModuleName(), $res);
+ return;
+ }
+
+ if(is_null($params['user']))
+ $this->dieUsage('The user parameter must be set', 'nouser');
+ if(is_null($params['token']))
+ $this->dieUsage('The token parameter must be set', 'notoken');
+ if(!$wgUser->matchEditToken($params['token']))
+ $this->dieUsage('Invalid token', 'badtoken');
+ if(!$wgUser->isAllowed('block'))
+ $this->dieUsage('You don\'t have permission to block users', 'permissiondenied');
+ if($params['hidename'] && !$wgUser->isAllowed('hideuser'))
+ $this->dieUsage('You don\'t have permission to hide user names from the block log', 'nohide');
+ if(wfReadOnly())
+ $this->dieUsage('The wiki is in read-only mode', 'readonly');
+
+ $form = new IPBlockForm('');
+ $form->BlockAddress = $params['user'];
+ $form->BlockReason = $params['reason'];
+ $form->BlockReasonList = 'other';
+ $form->BlockExpiry = ($params['expiry'] == 'never' ? 'infinite' : $params['expiry']);
+ $form->BlockOther = '';
+ $form->BlockAnonOnly = $params['anononly'];
+ $form->BlockCreateAccount = $params['nocreate'];
+ $form->BlockEnableAutoBlock = $params['autoblock'];
+ $form->BlockEmail = $params['noemail'];
+ $form->BlockHideName = $params['hidename'];
+
+ $dbw = wfGetDb(DB_MASTER);
+ $dbw->begin();
+ $retval = $form->doBlock($userID, $expiry);
+ switch($retval)
+ {
+ case IPBlockForm::BLOCK_SUCCESS:
+ break; // We'll deal with that later
+ case IPBlockForm::BLOCK_RANGE_INVALID:
+ $this->dieUsage("Invalid IP range ``{$params['user']}''", 'invalidrange');
+ case IPBlockForm::BLOCK_RANGE_DISABLED:
+ $this->dieUsage('Blocking IP ranges has been disabled', 'rangedisabled');
+ case IPBlockForm::BLOCK_NONEXISTENT_USER:
+ $this->dieUsage("User ``{$params['user']}'' doesn't exist", 'nosuchuser');
+ case IPBlockForm::BLOCK_IP_INVALID:
+ $this->dieUsage("Invaild IP address ``{$params['user']}''", 'invalidip');
+ case IPBlockForm::BLOCK_EXPIRY_INVALID:
+ $this->dieUsage("Invalid expiry time ``{$params['expiry']}''", 'invalidexpiry');
+ case IPBlockForm::BLOCK_ALREADY_BLOCKED:
+ $this->dieUsage("User ``{$params['user']}'' is already blocked", 'alreadyblocked');
+ default:
+ $this->dieDebug(__METHOD__, "IPBlockForm::doBlock() returned an unknown error ($retval)");
+ }
+ $dbw->commit();
+
+ $res['user'] = $params['user'];
+ $res['userID'] = $userID;
+ $res['expiry'] = ($expiry == Block::infinity() ? 'infinite' : $expiry);
+ $res['reason'] = $params['reason'];
+ if($params['anononly'])
+ $res['anononly'] = '';
+ if($params['nocreate'])
+ $res['nocreate'] = '';
+ if($params['autoblock'])
+ $res['autoblock'] = '';
+ if($params['noemail'])
+ $res['noemail'] = '';
+ if($params['hidename'])
+ $res['hidename'] = '';
+
+ $this->getResult()->addValue(null, $this->getModuleName(), $res);
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'user' => null,
+ 'token' => null,
+ 'gettoken' => false,
+ 'expiry' => 'never',
+ 'reason' => null,
+ 'anononly' => false,
+ 'nocreate' => false,
+ 'autoblock' => false,
+ 'noemail' => false,
+ 'hidename' => false,
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'user' => 'Username, IP address or IP range you want to block',
+ 'token' => 'A block token previously obtained through the gettoken parameter',
+ 'gettoken' => 'If set, a block token will be returned, and no other action will be taken',
+ 'expiry' => 'Relative expiry time, e.g. \'5 months\' or \'2 weeks\'. If set to \'infinite\', \'indefinite\' or \'never\', the block will never expire.',
+ 'reason' => 'Reason for block (optional)',
+ 'anononly' => 'Block anonymous users only (i.e. disable anonymous edits for this IP)',
+ 'nocreate' => 'Prevent account creation',
+ 'autoblock' => 'Automatically block the last used IP address, and any subsequent IP addresses they try to login from',
+ 'noemail' => 'Prevent user from sending e-mail through the wiki',
+ 'hidename' => 'Hide the username from the block log.'
+ );
+ }
+
+ protected function getDescription() {
+ return array(
+ 'Block a user.'
+ );
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=block&user=123.5.5.12&expiry=3%20days&reason=First%20strike',
+ 'api.php?action=block&user=Vandal&expiry=never&reason=Vandalism&nocreate&autoblock&noemail'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
--- /dev/null
+<?php
+
+/*
+ * Created on Sep 11, 2007
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ("ApiBase.php");
+}
+
+/**
+ * @addtogroup API
+ */
+class ApiChangeRights extends ApiBase {
+
+ public function __construct($main, $action) {
+ parent :: __construct($main, $action);
+ }
+
+ public function execute() {
+ global $wgUser, $wgRequest;
+ $this->getMain()->requestWriteMode();
+
+ if(wfReadOnly())
+ $this->dieUsage('The wiki is in read-only mode', 'readonly');
+ $params = $this->extractRequestParams();
+
+ $ur = new UserrightsForm($wgRequest);
+ $allowed = $ur->changeableGroups();
+ $res = array();
+
+ if(is_null($params['user']))
+ $this->dieUsage('The user parameter must be set', 'nouser');
+
+ $uName = User::getCanonicalName($params['user']);
+ $u = User::newFromName($uName);
+ if(!$u)
+ $this->dieUsage("Invalid username ``{$params['user']}''", 'invaliduser');
+ if($u->getId() == 0) // Anon or non-existent
+ $this->dieUsage("User ``{$params['user']}'' doesn't exist", 'nosuchuser');
+
+ $curgroups = $u->getGroups();
+
+ if($params['listgroups'])
+ {
+ $res['user'] = $uName;
+ $res['allowedgroups'] = $allowed;
+ $res['ingroups'] = $curgroups;
+ $this->getResult()->setIndexedTagName($res['ingroups'], 'group');
+ $this->getResult()->setIndexedTagName($res['allowedgroups']['add'], 'group');
+ $this->getResult()->setIndexedTagName($res['allowedgroups']['remove'], 'group');
+ }
+;
+ if($params['gettoken'])
+ {
+ $res['changerightstoken'] = $wgUser->editToken($uName);
+ $this->getResult()->addValue(null, $this->getModuleName(), $res);
+ return;
+ }
+
+ if(empty($params['addto']) && empty($params['rmfrom']))
+ $this->dieUsage('At least one of the addto and rmfrom parameters must be set', 'noaddrm');
+ if(is_null($params['token']))
+ $this->dieUsage('The token parameter must be set', 'notoken');
+ if(!$wgUser->matchEditToken($params['token'], $uName))
+ $this->dieUsage('Invalid token', 'badtoken');
+
+ if(!$wgUser->isAllowed('userrights'))
+ $this->dieUsage('You don\'t have permission to change users\' rights', 'permissiondenied');
+
+ // First let's remove redundant groups and check permissions while we're at it
+ if(is_null($params['addto']))
+ $params['addto'] = array();
+ $addto = array();
+ foreach($params['addto'] as $g)
+ {
+ if(!in_array($g, $allowed['add']))
+ $this->dieUsage("You don't have permission to add to group ``$g''", 'cantadd');
+ if(!in_array($g, $curgroups))
+ $addto[] = $g;
+ }
+
+ if(is_null($params['rmfrom']))
+ $params['rmfrom'] = array();
+ $rmfrom = array();
+ foreach($params['rmfrom'] as $g)
+ {
+ if(!in_array($g, $allowed['remove']))
+ $this->dieUsage("You don't have permission to remove from group ``$g''", 'cantremove');
+ if(in_array($g, $curgroups))
+ $rmfrom[] = $g;
+ }
+ $dbw = wfGetDb(DB_MASTER);
+ $dbw->begin();
+ $ur->doSaveUserGroups($u, $rmfrom, $addto, $params['reason']);
+ $dbw->commit();
+ $res['user'] = $uName;
+ $res['addedto'] = $addto;
+ $res['removedfrom'] = $rmfrom;
+ $res['reason'] = $params['reason'];
+
+ $this->getResult()->setIndexedTagName($res['addedto'], 'group');
+ $this->getResult()->setIndexedTagName($res['removedfrom'], 'group');
+ $this->getResult()->addValue(null, $this->getModuleName(), $res);
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'user' => null,
+ 'token' => null,
+ 'gettoken' => false,
+ 'listgroups' => false,
+ 'addto' => array(
+ ApiBase :: PARAM_ISMULTI => true,
+ ),
+ 'rmfrom' => array(
+ ApiBase :: PARAM_ISMULTI => true,
+ ),
+ 'reason' => ''
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'user' => 'The user you want to add to or remove from groups.',
+ 'token' => 'A changerights token previously obtained through the gettoken parameter.',
+ 'gettoken' => 'Output a token. Note that the user parameter still has to be set.',
+ 'listgroups' => 'List the groups the user is in, and the ones you can add them to and remove them from.',
+ 'addto' => 'Pipe-separated list of groups to add this user to',
+ 'rmfrom' => 'Pipe-separated list of groups to remove this user from',
+ 'reason' => 'Reason for change (optional)'
+ );
+ }
+
+ protected function getDescription() {
+ return array(
+ 'Add or remove a user from certain groups.'
+ );
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=changerights&user=Bob&gettoken&listgroups',
+ 'api.php?action=changerights&user=Bob&token=123ABC&addto=sysop&reason=Promoting%20per%20RFA'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
--- /dev/null
+<?php
+
+/*
+ * Created on Jun 30, 2007
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ("ApiBase.php");
+}
+
+
+/**
+ * @addtogroup API
+ */
+class ApiDelete extends ApiBase {
+
+ public function __construct($main, $action) {
+ parent :: __construct($main, $action);
+ }
+
+ /**
+ * We have our own delete() function, since Article.php's implementation is split in two phases
+ * @param Article $article - Article object to work on
+ * @param string $token - Delete token (same as edit token)
+ * @param string $reason - Reason for the deletion. Autogenerated if NULL
+ * @return DELETE_SUCCESS on success, DELETE_* on failure
+ */
+
+ const DELETE_SUCCESS = 0;
+ const DELETE_PERM = 1;
+ const DELETE_BLOCKED = 2;
+ const DELETE_READONLY = 3;
+ const DELETE_BADTOKEN = 4;
+ const DELETE_BADARTICLE = 5;
+
+ public static function delete(&$article, $token, &$reason = NULL)
+ {
+ global $wgUser;
+
+ // Check permissions first
+ if(!$article->mTitle->userCan('delete'))
+ return self::DELETE_PERM;
+ if($wgUser->isBlocked())
+ return self::DELETE_BLOCKED;
+ if(wfReadOnly())
+ return self::DELETE_READONLY;
+
+ // Check token
+ if(!$wgUser->matchEditToken($token))
+ return self::DELETE_BADTOKEN;
+
+ // Auto-generate a summary, if necessary
+ if(is_null($reason))
+ {
+ $reason = $article->generateReason($hasHistory);
+ if($reason === false)
+ return self::DELETE_BADARTICLE;
+ }
+
+ // Luckily, Article.php provides a reusable delete function that does the hard work for us
+ if($article->doDeleteArticle($reason))
+ return self::DELETE_SUCCESS;
+ return self::DELETE_BADARTICLE;
+ }
+
+ public function execute() {
+ global $wgUser;
+ $this->getMain()->requestWriteMode();
+ $params = $this->extractRequestParams();
+
+ $titleObj = NULL;
+ if(!isset($params['title']))
+ $this->dieUsage('The title parameter must be set', 'notitle');
+ if(!isset($params['token']))
+ $this->dieUsage('The token parameter must be set', 'notoken');
+
+ // delete() also checks for these, but we wanna save some work
+ if(!$wgUser->isAllowed('delete'))
+ $this->dieUsage('You don\'t have permission to delete pages', 'permissiondenied');
+ if($wgUser->isBlocked())
+ $this->dieUsage('You have been blocked from editing', 'blocked');
+ if(wfReadOnly())
+ $this->dieUsage('The wiki is in read-only mode', 'readonly');
+
+ $titleObj = Title::newFromText($params['title']);
+ if(!$titleObj)
+ $this->dieUsage("Bad title ``{$params['title']}''", 'invalidtitle');
+ if(!$titleObj->exists())
+ $this->dieUsage("``{$params['title']}'' doesn't exist", 'missingtitle');
+
+ $articleObj = new Article($titleObj);
+ $reason = (isset($params['reason']) ? $params['reason'] : NULL);
+ $dbw = wfGetDb(DB_MASTER);
+ $dbw->begin();
+ $retval = self::delete(&$articleObj, $params['token'], &$reason);
+
+ switch($retval)
+ {
+ case self::DELETE_SUCCESS:
+ break; // We'll deal with that later
+ case self::DELETE_PERM: // If we get PERM, BLOCKED or READONLY that's weird, but it's possible
+ $this->dieUsage('You don\'t have permission to delete', 'permissiondenied');
+ case self::DELETE_BLOCKED:
+ $this->dieUsage('You have been blocked from editing', 'blocked');
+ case self::DELETE_READONLY:
+ $this->dieUsage('The wiki is in read-only mode', 'readonly');
+ case self::DELETE_BADTOKEN:
+ $this->dieUsage('Invalid token', 'badtoken');
+ case self::DELETE_BADARTICLE:
+ $this->dieUsage("The article ``{$params['title']}'' doesn't exist or has already been deleted", 'missingtitle');
+ default:
+ // delete() has apparently invented a new error, which is extremely weird
+ $this->dieDebug(__METHOD__, "delete() returned an unknown error ($retval)");
+ }
+ // $retval has to be self::DELETE_SUCCESS if we get here
+ $dbw->commit();
+ $r = array('title' => $titleObj->getPrefixedText(), 'reason' => $reason);
+ $this->getResult()->addValue(null, $this->getModuleName(), $r);
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'title' => null,
+ 'token' => null,
+ 'reason' => null,
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'title' => 'Title of the page you want to delete.',
+ 'token' => 'A delete token previously retrieved through prop=info',
+ 'reason' => 'Reason for the deletion. If not set, an automatically generated reason will be used.'
+ );
+ }
+
+ protected function getDescription() {
+ return array(
+ 'Deletes a page. You need to be logged in as a sysop to use this function, see also action=login.'
+ );
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=delete&title=Main%20Page&token=123ABC',
+ 'api.php?action=delete&title=Main%20Page&token=123ABC&reason=Preparing%20for%20move'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
--- /dev/null
+<?php
+
+/*
+ * Created on Oct 31, 2007
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ("ApiBase.php");
+}
+
+
+/**
+ * @addtogroup API
+ */
+class ApiMove extends ApiBase {
+
+ public function __construct($main, $action) {
+ parent :: __construct($main, $action);
+ }
+
+ public function execute() {
+ global $wgUser;
+ $this->getMain()->requestWriteMode();
+ $params = $this->extractRequestParams();
+ if(is_null($params['reason']))
+ $params['reason'] = '';
+
+ $titleObj = NULL;
+ if(!isset($params['from']))
+ $this->dieUsage('The from parameter must be set', 'nofrom');
+ if(!isset($params['to']))
+ $this->dieUsage('The to parameter must be set', 'noto');
+ if(!isset($params['token']))
+ $this->dieUsage('The token parameter must be set', 'notoken');
+ if(!$wgUser->matchEditToken($params['token']))
+ $this->dieUsage('Invalid token', 'badtoken');
+
+ if($wgUser->isBlocked())
+ $this->dieUsage('You have been blocked from editing', 'blocked');
+ if(wfReadOnly())
+ $this->dieUsage('The wiki is in read-only mode', 'readonly');
+ if($params['noredirect'] && !$wgUser->isAllowed('suppressredirect'))
+ $this->dieUsage("You don't have permission to suppress redirect creation", 'nosuppress');
+
+ $fromTitle = Title::newFromText($params['from']);
+ if(!$fromTitle)
+ $this->dieUsage("Bad title ``{$params['from']}''", 'invalidtitle');
+ if(!$fromTitle->exists())
+ $this->dieUsage("``{$params['from']}'' doesn't exist", 'missingtitle');
+ $fromTalk = $fromTitle->getTalkPage();
+
+
+ $toTitle = Title::newFromText($params['to']);
+ if(!$toTitle)
+ $this->dieUsage("Bad title ``{$params['to']}''", 'invalidtitle');
+ $toTalk = $toTitle->getTalkPage();
+
+ $dbw = wfGetDB(DB_MASTER);
+ $dbw->begin();
+ $retval = $fromTitle->moveTo($toTitle, true, $params['reason'], !$params['noredirect']);
+ if($retval !== true)
+ switch($retval)
+ {
+ // case 'badtitletext': Can't happen
+ // case 'badarticleerror': Can't happen
+ case 'selfmove':
+ $this->dieUsage("Can't move ``{$params['from']}'' to itself", 'selfmove');
+ case 'immobile_namespace':
+ if($fromTitle->isMovable())
+ $this->dieUsage("Pages in the ``{$fromTitle->getNsText()}'' namespace can't be moved", 'immobilenamespace-from');
+ $this->dieUsage("Pages in the ``{$toTitle->getNsText()}'' namespace can't be moved", 'immobilenamespace-to');
+ case 'articleexists':
+ $this->dieUsage("``{$toTitle->getPrefixedText()}'' already exists and is not a redirect to ``{$fromTitle->getPrefixedText()}''", 'targetexists');
+ case 'protectedpage':
+ $this->dieUsage("You don't have permission to move ``{$fromTitle->getPrefixedText()}'' to ``{$toTitle->getPrefixedText()}''", 'permissiondenied');
+ default:
+ throw new MWException( "Title::moveTo: Unknown return value ``{$retval}''" );
+ }
+ $r = array('from' => $fromTitle->getPrefixedText(), 'to' => $toTitle->getPrefixedText(), 'reason' => $params['reason']);
+ if(!$params['noredirect'])
+ $r['redirectcreated'] = '';
+
+ if($params['movetalk'] && $fromTalk->exists() && !$fromTitle->isTalkPage())
+ {
+ // We need to move the talk page as well
+ $toTalk = $toTitle->getTalkPage();
+ $retval = $fromTalk->moveTo($toTalk, true, $params['reason'], !$params['noredirect']);
+ if($retval === true)
+ {
+ $r['talkfrom'] = $fromTalk->getPrefixedText();
+ $r['talkto'] = $toTalk->getPrefixedText();
+ }
+ // We're not gonna dieUsage() on failure, since we already changed something
+ else
+ switch($retval)
+ {
+ case 'immobile_namespace':
+ if($fromTalk->isMovable())
+ {
+ $r['talkmove-error-code'] = 'immobilenamespace-from';
+ $r['talkmove-error-info'] = "Pages in the ``{$fromTalk->getNsText()}'' namespace can't be moved";
+ }
+ else
+ {
+ $r['talkmove-error-code'] = 'immobilenamespace-to';
+ $r['talkmove-error-info'] = "Pages in the ``{$toTalk->getNsText()}'' namespace can't be moved";
+ }
+ break;
+ case 'articleexists':
+ $r['talkmove-error-code'] = 'targetexists';
+ $r['talkmove-error-info'] = "``{$toTalk->getPrefixedText()}'' already exists and is not a redirect to ``{$fromTalk->getPrefixedText()}''";
+ break;
+ case 'protectedpage':
+ $r['talkmove-error-code'] = 'permissiondenied';
+ $r['talkmove-error-info'] = "You don't have permission to move ``{$fromTalk->getPrefixedText()}'' to ``{$toTalk->getPrefixedText()}''";
+ default:
+ $r['talkmove-error-code'] = 'unknownerror';
+ $r['talkmove-error-info'] = "Unknown error ``$retval''";
+ }
+ }
+ $dbw->commit(); // Make sure all changes are really written to the DB
+ $this->getResult()->addValue(null, $this->getModuleName(), $r);
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'from' => null,
+ 'to' => null,
+ 'token' => null,
+ 'reason' => null,
+ 'movetalk' => false,
+ 'noredirect' => false
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'from' => 'Title of the page you want to move.',
+ 'to' => 'Title you want to rename the page to.',
+ 'token' => 'A move token previously retrieved through prop=info',
+ 'reason' => 'Reason for the move (optional).',
+ 'movetalk' => 'Move the talk page, if it exists.',
+ 'noredirect' => 'Don\'t create a redirect'
+ );
+ }
+
+ protected function getDescription() {
+ return array(
+ 'Moves a page.'
+ );
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=move&from=Exampel&to=Example&token=123ABC&reason=Misspelled%20title&movetalk&noredirect'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
--- /dev/null
+<?php
+
+/*
+ * Created on Sep 1, 2007
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ("ApiBase.php");
+}
+
+/**
+ * @addtogroup API
+ */
+class ApiProtect extends ApiBase {
+
+ public function __construct($main, $action) {
+ parent :: __construct($main, $action);
+ }
+
+ public function execute() {
+ global $wgUser;
+ $this->getMain()->requestWriteMode();
+ $params = $this->extractRequestParams();
+
+ $titleObj = NULL;
+ if(!isset($params['title']))
+ $this->dieUsage('The title parameter must be set', 'notitle');
+ if(!isset($params['token']))
+ $this->dieUsage('The token parameter must be set', 'notoken');
+ if(!isset($params['protections']) || empty($params['protections']))
+ $this->dieUsage('The protections parameter must be set', 'noprotections');
+
+ if($wgUser->isBlocked())
+ $this->dieUsage('You have been blocked from editing', 'blocked');
+ if(wfReadOnly())
+ $this->dieUsage('The wiki is in read-only mode', 'readonly');
+ if(!$wgUser->matchEditToken($params['token']))
+ $this->dieUsage('Invalid token', 'badtoken');
+
+ $titleObj = Title::newFromText($params['title']);
+ if(!$titleObj)
+ $this->dieUsage("Bad title ``{$params['title']}''", 'invalidtitle');
+ if(!$titleObj->exists())
+ $this->dieUsage("``{$params['title']}'' doesn't exist", 'missingtitle');
+ if(!$titleObj->userCan('protect'))
+ $this->dieUsage('You don\'t have permission to change protection levels', 'permissiondenied');
+ $articleObj = new Article($titleObj);
+
+ if(in_array($params['expiry'], array('infinite', 'indefinite', 'never')))
+ $expiry = Block::infinity();
+ else
+ {
+ $expiry = strtotime($params['expiry']);
+ if($expiry < 0 || $expiry == false)
+ $this->dieUsage('Invalid expiry time', 'invalidexpiry');
+
+ $expiry = wfTimestamp(TS_MW, $expiry);
+ if($expiry < wfTimestampNow())
+ $this->dieUsage('Expiry time is in the past', 'pastexpiry');
+ }
+
+ $protections = array();
+ foreach($params['protections'] as $prot)
+ {
+ $p = explode('=', $prot);
+ $protections[$p[0]] = ($p[1] == 'all' ? '' : $p[1]);
+ }
+
+ $dbw = wfGetDb(DB_MASTER);
+ $dbw->begin();
+ $ok = $articleObj->updateRestrictions($protections, $params['reason'], $params['cascade'], $expiry);
+ if(!$ok)
+ // This is very weird. Maybe the article was deleted or the user was blocked/desysopped in the meantime?
+ $this->dieUsage('Unknown error', 'unknownerror');
+ $dbw->commit();
+ $res = array('title' => $titleObj->getPrefixedText(), 'reason' => $params['reason'], 'expiry' => $expiry);
+ if($params['cascade'])
+ $res['cascade'] = '';
+ $res['protections'] = $protections;
+ $this->getResult()->addValue(null, $this->getModuleName(), $res);
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'title' => null,
+ 'token' => null,
+ 'protections' => array(
+ ApiBase :: PARAM_ISMULTI => true
+ ),
+ 'expiry' => 'infinite',
+ 'reason' => '',
+ 'cascade' => false
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'title' => 'Title of the page you want to restore.',
+ 'token' => 'A protect token previously retrieved through prop=info',
+ 'protections' => 'Pipe-separated list of protection levels, formatted action=group (e.g. edit=sysop)',
+ 'expiry' => 'Expiry timestamp. If set to \'infinite\', \'indefinite\' or \'never\', the protection will never expire.',
+ 'reason' => 'Reason for (un)protecting (optional)',
+ 'cascade' => 'Enable cascading protection (i.e. protect pages included in this page)'
+ );
+ }
+
+ protected function getDescription() {
+ return array(
+ 'Change the protection level of a page.'
+ );
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=protect&title=Main%20Page&token=123ABC&protections=edit=sysop|move=sysop&cascade&expiry=20070901163000',
+ 'api.php?action=protect&title=Main%20Page&token=123ABC&protections=edit=all|move=all&reason=Lifting%20restrictions'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
--- /dev/null
+<?php
+
+/*
+ * Created on Sep 7, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiBase.php');
+}
+
+/**
+ * This is the main query class. It behaves similar to ApiMain: based on the parameters given,
+ * it will create a list of titles to work on (an instance of the ApiPageSet object)
+ * instantiate and execute various property/list/meta modules,
+ * and assemble all resulting data into a single ApiResult object.
+ *
+ * In the generator mode, a generator will be first executed to populate a second ApiPageSet object,
+ * and that object will be used for all subsequent modules.
+ *
+ * @addtogroup API
+ */
+class ApiQuery extends ApiBase {
+
+ private $mPropModuleNames, $mListModuleNames, $mMetaModuleNames;
+ private $mPageSet;
+ private $params, $redirect;
+
+ private $mQueryPropModules = array (
+ 'info' => 'ApiQueryInfo',
+ 'revisions' => 'ApiQueryRevisions',
+ 'links' => 'ApiQueryLinks',
+ 'langlinks' => 'ApiQueryLangLinks',
+ 'images' => 'ApiQueryImages',
+ 'imageinfo' => 'ApiQueryImageInfo',
+ 'templates' => 'ApiQueryLinks',
+ 'categories' => 'ApiQueryCategories',
+ 'extlinks' => 'ApiQueryExternalLinks',
+ );
+
+ private $mQueryListModules = array (
+ 'allpages' => 'ApiQueryAllpages',
+ 'alllinks' => 'ApiQueryAllLinks',
+ 'allusers' => 'ApiQueryAllUsers',
+ 'backlinks' => 'ApiQueryBacklinks',
+ 'blocks' => 'ApiQueryBlocks',
+ 'categorymembers' => 'ApiQueryCategoryMembers',
+ 'deletedrevs' => 'ApiQueryDeletedrevs',
+ 'embeddedin' => 'ApiQueryBacklinks',
+ 'imageusage' => 'ApiQueryBacklinks',
+ 'logevents' => 'ApiQueryLogEvents',
+ 'recentchanges' => 'ApiQueryRecentChanges',
+ 'search' => 'ApiQuerySearch',
+ 'usercontribs' => 'ApiQueryContributions',
+ 'watchlist' => 'ApiQueryWatchlist',
+ 'exturlusage' => 'ApiQueryExtLinksUsage',
+ );
+
+ private $mQueryMetaModules = array (
+ 'siteinfo' => 'ApiQuerySiteinfo',
+ 'userinfo' => 'ApiQueryUserInfo',
+ 'allmessages' => 'ApiQueryAllmessages',
+ );
+
+ private $mSlaveDB = null;
+ private $mNamedDB = array();
+
+ public function __construct($main, $action) {
+ parent :: __construct($main, $action);
+
+ // Allow custom modules to be added in LocalSettings.php
+ global $wgApiQueryPropModules, $wgApiQueryListModules, $wgApiQueryMetaModules;
+ self :: appendUserModules($this->mQueryPropModules, $wgApiQueryPropModules);
+ self :: appendUserModules($this->mQueryListModules, $wgApiQueryListModules);
+ self :: appendUserModules($this->mQueryMetaModules, $wgApiQueryMetaModules);
+
+ $this->mPropModuleNames = array_keys($this->mQueryPropModules);
+ $this->mListModuleNames = array_keys($this->mQueryListModules);
+ $this->mMetaModuleNames = array_keys($this->mQueryMetaModules);
+
+ // Allow the entire list of modules at first,
+ // but during module instantiation check if it can be used as a generator.
+ $this->mAllowedGenerators = array_merge($this->mListModuleNames, $this->mPropModuleNames);
+ }
+
+ /**
+ * Helper function to append any add-in modules to the list
+ */
+ private static function appendUserModules(&$modules, $newModules) {
+ if (is_array( $newModules )) {
+ foreach ( $newModules as $moduleName => $moduleClass) {
+ $modules[$moduleName] = $moduleClass;
+ }
+ }
+ }
+
+ /**
+ * Gets a default slave database connection object
+ */
+ public function getDB() {
+ if (!isset ($this->mSlaveDB)) {
+ $this->profileDBIn();
+ $this->mSlaveDB = wfGetDB(DB_SLAVE);
+ $this->profileDBOut();
+ }
+ return $this->mSlaveDB;
+ }
+
+ /**
+ * Get the query database connection with the given name.
+ * If no such connection has been requested before, it will be created.
+ * Subsequent calls with the same $name will return the same connection
+ * as the first, regardless of $db or $groups new values.
+ */
+ public function getNamedDB($name, $db, $groups) {
+ if (!array_key_exists($name, $this->mNamedDB)) {
+ $this->profileDBIn();
+ $this->mNamedDB[$name] = wfGetDB($db, $groups);
+ $this->profileDBOut();
+ }
+ return $this->mNamedDB[$name];
+ }
+
+ /**
+ * Gets the set of pages the user has requested (or generated)
+ */
+ public function getPageSet() {
+ return $this->mPageSet;
+ }
+
+ /**
+ * Query execution happens in the following steps:
+ * #1 Create a PageSet object with any pages requested by the user
+ * #2 If using generator, execute it to get a new PageSet object
+ * #3 Instantiate all requested modules.
+ * This way the PageSet object will know what shared data is required,
+ * and minimize DB calls.
+ * #4 Output all normalization and redirect resolution information
+ * #5 Execute all requested modules
+ */
+ public function execute() {
+
+ $this->params = $this->extractRequestParams();
+ $this->redirects = $this->params['redirects'];
+
+ //
+ // Create PageSet
+ //
+ $this->mPageSet = new ApiPageSet($this, $this->redirects);
+
+ //
+ // Instantiate requested modules
+ //
+ $modules = array ();
+ $this->InstantiateModules($modules, 'prop', $this->mQueryPropModules);
+ $this->InstantiateModules($modules, 'list', $this->mQueryListModules);
+ $this->InstantiateModules($modules, 'meta', $this->mQueryMetaModules);
+
+ //
+ // If given, execute generator to substitute user supplied data with generated data.
+ //
+ if (isset ($this->params['generator'])) {
+ $this->executeGeneratorModule($this->params['generator'], $modules);
+ } else {
+ // Append custom fields and populate page/revision information
+ $this->addCustomFldsToPageSet($modules, $this->mPageSet);
+ $this->mPageSet->execute();
+ }
+
+ //
+ // Record page information (title, namespace, if exists, etc)
+ //
+ $this->outputGeneralPageInfo();
+
+ //
+ // Execute all requested modules.
+ //
+ foreach ($modules as $module) {
+ $module->profileIn();
+ $module->execute();
+ $module->profileOut();
+ }
+ }
+
+ /**
+ * Query modules may optimize data requests through the $this->getPageSet() object
+ * by adding extra fields from the page table.
+ * This function will gather all the extra request fields from the modules.
+ */
+ private function addCustomFldsToPageSet($modules, $pageSet) {
+ // Query all requested modules.
+ foreach ($modules as $module) {
+ $module->requestExtraData($pageSet);
+ }
+ }
+
+ /**
+ * Create instances of all modules requested by the client
+ */
+ private function InstantiateModules(&$modules, $param, $moduleList) {
+ $list = $this->params[$param];
+ if (isset ($list))
+ foreach ($list as $moduleName)
+ $modules[] = new $moduleList[$moduleName] ($this, $moduleName);
+ }
+
+ /**
+ * Appends an element for each page in the current pageSet with the most general
+ * information (id, title), plus any title normalizations and missing title/pageids/revids.
+ */
+ private function outputGeneralPageInfo() {
+
+ $pageSet = $this->getPageSet();
+ $result = $this->getResult();
+
+ // Title normalizations
+ $normValues = array ();
+ foreach ($pageSet->getNormalizedTitles() as $rawTitleStr => $titleStr) {
+ $normValues[] = array (
+ 'from' => $rawTitleStr,
+ 'to' => $titleStr
+ );
+ }
+
+ if (!empty ($normValues)) {
+ $result->setIndexedTagName($normValues, 'n');
+ $result->addValue('query', 'normalized', $normValues);
+ }
+
+ // Interwiki titles
+ $intrwValues = array ();
+ foreach ($pageSet->getInterwikiTitles() as $rawTitleStr => $interwikiStr) {
+ $intrwValues[] = array (
+ 'title' => $rawTitleStr,
+ 'iw' => $interwikiStr
+ );
+ }
+
+ if (!empty ($intrwValues)) {
+ $result->setIndexedTagName($intrwValues, 'i');
+ $result->addValue('query', 'interwiki', $intrwValues);
+ }
+
+ // Show redirect information
+ $redirValues = array ();
+ foreach ($pageSet->getRedirectTitles() as $titleStrFrom => $titleStrTo) {
+ $redirValues[] = array (
+ 'from' => $titleStrFrom,
+ 'to' => $titleStrTo
+ );
+ }
+
+ if (!empty ($redirValues)) {
+ $result->setIndexedTagName($redirValues, 'r');
+ $result->addValue('query', 'redirects', $redirValues);
+ }
+
+ //
+ // Missing revision elements
+ //
+ $missingRevIDs = $pageSet->getMissingRevisionIDs();
+ if (!empty ($missingRevIDs)) {
+ $revids = array ();
+ foreach ($missingRevIDs as $revid) {
+ $revids[$revid] = array (
+ 'revid' => $revid
+ );
+ }
+ $result->setIndexedTagName($revids, 'rev');
+ $result->addValue('query', 'badrevids', $revids);
+ }
+
+ //
+ // Page elements
+ //
+ $pages = array ();
+
+ // Report any missing titles
+ foreach ($pageSet->getMissingTitles() as $fakeId => $title) {
+ $vals = array();
+ ApiQueryBase :: addTitleInfo($vals, $title);
+ $vals['missing'] = '';
+ $pages[$fakeId] = $vals;
+ }
+
+ // Report any missing page ids
+ foreach ($pageSet->getMissingPageIDs() as $pageid) {
+ $pages[$pageid] = array (
+ 'pageid' => $pageid,
+ 'missing' => ''
+ );
+ }
+
+ // Output general page information for found titles
+ foreach ($pageSet->getGoodTitles() as $pageid => $title) {
+ $vals = array();
+ $vals['pageid'] = $pageid;
+ ApiQueryBase :: addTitleInfo($vals, $title);
+ $pages[$pageid] = $vals;
+ }
+
+ if (!empty ($pages)) {
+
+ if ($this->params['indexpageids']) {
+ $pageIDs = array_keys($pages);
+ // json treats all map keys as strings - converting to match
+ $pageIDs = array_map('strval', $pageIDs);
+ $result->setIndexedTagName($pageIDs, 'id');
+ $result->addValue('query', 'pageids', $pageIDs);
+ }
+
+ $result->setIndexedTagName($pages, 'page');
+ $result->addValue('query', 'pages', $pages);
+ }
+ }
+
+ /**
+ * For generator mode, execute generator, and use its output as new pageSet
+ */
+ protected function executeGeneratorModule($generatorName, $modules) {
+
+ // Find class that implements requested generator
+ if (isset ($this->mQueryListModules[$generatorName])) {
+ $className = $this->mQueryListModules[$generatorName];
+ } elseif (isset ($this->mQueryPropModules[$generatorName])) {
+ $className = $this->mQueryPropModules[$generatorName];
+ } else {
+ ApiBase :: dieDebug(__METHOD__, "Unknown generator=$generatorName");
+ }
+
+ // Generator results
+ $resultPageSet = new ApiPageSet($this, $this->redirects);
+
+ // Create and execute the generator
+ $generator = new $className ($this, $generatorName);
+ if (!$generator instanceof ApiQueryGeneratorBase)
+ $this->dieUsage("Module $generatorName cannot be used as a generator", "badgenerator");
+
+ $generator->setGeneratorMode();
+
+ // Add any additional fields modules may need
+ $generator->requestExtraData($this->mPageSet);
+ $this->addCustomFldsToPageSet($modules, $resultPageSet);
+
+ // Populate page information with the original user input
+ $this->mPageSet->execute();
+
+ // populate resultPageSet with the generator output
+ $generator->profileIn();
+ $generator->executeGenerator($resultPageSet);
+ $resultPageSet->finishPageSetGeneration();
+ $generator->profileOut();
+
+ // Swap the resulting pageset back in
+ $this->mPageSet = $resultPageSet;
+ }
+
+ /**
+ * Returns the list of allowed parameters for this module.
+ * Qurey module also lists all ApiPageSet parameters as its own.
+ */
+ protected function getAllowedParams() {
+ return array (
+ 'prop' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => $this->mPropModuleNames
+ ),
+ 'list' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => $this->mListModuleNames
+ ),
+ 'meta' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => $this->mMetaModuleNames
+ ),
+ 'generator' => array (
+ ApiBase :: PARAM_TYPE => $this->mAllowedGenerators
+ ),
+ 'redirects' => false,
+ 'indexpageids' => false,
+ );
+ }
+
+ /**
+ * Override the parent to generate help messages for all available query modules.
+ */
+ public function makeHelpMsg() {
+
+ $msg = '';
+
+ // Make sure the internal object is empty
+ // (just in case a sub-module decides to optimize during instantiation)
+ $this->mPageSet = null;
+ $this->mAllowedGenerators = array(); // Will be repopulated
+
+ $astriks = str_repeat('--- ', 8);
+ $msg .= "\n$astriks Query: Prop $astriks\n\n";
+ $msg .= $this->makeHelpMsgHelper($this->mQueryPropModules, 'prop');
+ $msg .= "\n$astriks Query: List $astriks\n\n";
+ $msg .= $this->makeHelpMsgHelper($this->mQueryListModules, 'list');
+ $msg .= "\n$astriks Query: Meta $astriks\n\n";
+ $msg .= $this->makeHelpMsgHelper($this->mQueryMetaModules, 'meta');
+
+ // Perform the base call last because the $this->mAllowedGenerators
+ // will be updated inside makeHelpMsgHelper()
+ // Use parent to make default message for the query module
+ $msg = parent :: makeHelpMsg() . $msg;
+
+ return $msg;
+ }
+
+ /**
+ * For all modules in $moduleList, generate help messages and join them together
+ */
+ private function makeHelpMsgHelper($moduleList, $paramName) {
+
+ $moduleDscriptions = array ();
+
+ foreach ($moduleList as $moduleName => $moduleClass) {
+ $module = new $moduleClass ($this, $moduleName, null);
+
+ $msg = ApiMain::makeHelpMsgHeader($module, $paramName);
+ $msg2 = $module->makeHelpMsg();
+ if ($msg2 !== false)
+ $msg .= $msg2;
+ if ($module instanceof ApiQueryGeneratorBase) {
+ $this->mAllowedGenerators[] = $moduleName;
+ $msg .= "Generator:\n This module may be used as a generator\n";
+ }
+ $moduleDscriptions[] = $msg;
+ }
+
+ return implode("\n", $moduleDscriptions);
+ }
+
+ /**
+ * Override to add extra parameters from PageSet
+ */
+ public function makeHelpMsgParameters() {
+ $psModule = new ApiPageSet($this);
+ return $psModule->makeHelpMsgParameters() . parent :: makeHelpMsgParameters();
+ }
+
+ // @todo should work correctly
+ public function shouldCheckMaxlag() {
+ return true;
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'prop' => 'Which properties to get for the titles/revisions/pageids',
+ 'list' => 'Which lists to get',
+ 'meta' => 'Which meta data to get about the site',
+ 'generator' => 'Use the output of a list as the input for other prop/list/meta items',
+ 'redirects' => 'Automatically resolve redirects',
+ 'indexpageids' => 'Include an additional pageids section listing all returned page IDs.'
+ );
+ }
+
+ protected function getDescription() {
+ return array (
+ 'Query API module allows applications to get needed pieces of data from the MediaWiki databases,',
+ 'and is loosely based on the Query API interface currently available on all MediaWiki servers.',
+ 'All data modifications will first have to use query to acquire a token to prevent abuse from malicious sites.'
+ );
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=query&prop=revisions&meta=siteinfo&titles=Main%20Page&rvprop=user|comment'
+ );
+ }
+
+ public function getVersion() {
+ $psModule = new ApiPageSet($this);
+ $vers = array ();
+ $vers[] = __CLASS__ . ': $Id$';
+ $vers[] = $psModule->getVersion();
+ return $vers;
+ }
+}
+
--- /dev/null
+<?php
+
+/*
+ * Created on July 7, 2007
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+/**
+ * Query module to enumerate links from all pages together.
+ *
+ * @addtogroup API
+ */
+class ApiQueryAllLinks extends ApiQueryGeneratorBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'al');
+ }
+
+ public function execute() {
+ $this->run();
+ }
+
+ public function executeGenerator($resultPageSet) {
+ $this->run($resultPageSet);
+ }
+
+ private function run($resultPageSet = null) {
+
+ $db = $this->getDB();
+ $params = $this->extractRequestParams();
+
+ $prop = array_flip($params['prop']);
+ $fld_ids = isset($prop['ids']);
+ $fld_title = isset($prop['title']);
+
+ if ($params['unique']) {
+ if (!is_null($resultPageSet))
+ $this->dieUsage($this->getModuleName() . ' cannot be used as a generator in unique links mode', 'params');
+ if ($fld_ids)
+ $this->dieUsage($this->getModuleName() . ' cannot return corresponding page ids in unique links mode', 'params');
+ $this->addOption('DISTINCT');
+ }
+
+ $this->addTables('pagelinks');
+ $this->addWhereFld('pl_namespace', $params['namespace']);
+
+ if (!is_null($params['from']))
+ $this->addWhere('pl_title>=' . $db->addQuotes(ApiQueryBase :: titleToKey($params['from'])));
+ if (isset ($params['prefix']))
+ $this->addWhere("pl_title LIKE '" . $db->escapeLike(ApiQueryBase :: titleToKey($params['prefix'])) . "%'");
+
+ if (is_null($resultPageSet)) {
+ $this->addFields(array (
+ 'pl_namespace',
+ 'pl_title'
+ ));
+ $this->addFieldsIf('pl_from', $fld_ids);
+ } else {
+ $this->addFields('pl_from');
+ $pageids = array();
+ }
+
+ $this->addOption('USE INDEX', 'pl_namespace');
+ $limit = $params['limit'];
+ $this->addOption('LIMIT', $limit+1);
+ $this->addOption('ORDER BY', 'pl_namespace, pl_title');
+
+ $res = $this->select(__METHOD__);
+
+ $data = array ();
+ $count = 0;
+ while ($row = $db->fetchObject($res)) {
+ if (++ $count > $limit) {
+ // We've reached the one extra which shows that there are additional pages to be had. Stop here...
+ // TODO: Security issue - if the user has no right to view next title, it will still be shown
+ $this->setContinueEnumParameter('from', ApiQueryBase :: keyToTitle($row->pl_title));
+ break;
+ }
+
+ if (is_null($resultPageSet)) {
+ $vals = array();
+ if ($fld_ids)
+ $vals['fromid'] = intval($row->pl_from);
+ if ($fld_title) {
+ $title = Title :: makeTitle($row->pl_namespace, $row->pl_title);
+ $vals['ns'] = intval($title->getNamespace());
+ $vals['title'] = $title->getPrefixedText();
+ }
+ $data[] = $vals;
+ } else {
+ $pageids[] = $row->pl_from;
+ }
+ }
+ $db->freeResult($res);
+
+ if (is_null($resultPageSet)) {
+ $result = $this->getResult();
+ $result->setIndexedTagName($data, 'l');
+ $result->addValue('query', $this->getModuleName(), $data);
+ } else {
+ $resultPageSet->populateFromPageIDs($pageids);
+ }
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'from' => null,
+ 'prefix' => null,
+ 'unique' => false,
+ 'prop' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_DFLT => 'title',
+ ApiBase :: PARAM_TYPE => array (
+ 'ids',
+ 'title'
+ )
+ ),
+ 'namespace' => array (
+ ApiBase :: PARAM_DFLT => 0,
+ ApiBase :: PARAM_TYPE => 'namespace'
+ ),
+ 'limit' => array (
+ ApiBase :: PARAM_DFLT => 10,
+ ApiBase :: PARAM_TYPE => 'limit',
+ ApiBase :: PARAM_MIN => 1,
+ ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+ )
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'from' => 'The page title to start enumerating from.',
+ 'prefix' => 'Search for all page titles that begin with this value.',
+ 'unique' => 'Only show unique links. Cannot be used with generator or prop=ids',
+ 'prop' => 'What pieces of information to include',
+ 'namespace' => 'The namespace to enumerate.',
+ 'limit' => 'How many total links to return.'
+ );
+ }
+
+ protected function getDescription() {
+ return 'Enumerate all links that point to a given namespace';
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=query&list=alllinks&alunique&alfrom=B',
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
--- /dev/null
+<?php
+
+/*
+ * Created on July 7, 2007
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2007 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+/**
+ * Query module to enumerate all registered users.
+ *
+ * @addtogroup API
+ */
+class ApiQueryAllUsers extends ApiQueryBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'au');
+ }
+
+ public function execute() {
+ $db = $this->getDB();
+ $params = $this->extractRequestParams();
+
+ $prop = $params['prop'];
+ if (!is_null($prop)) {
+ $prop = array_flip($prop);
+ $fld_editcount = isset($prop['editcount']);
+ $fld_groups = isset($prop['groups']);
+ $fld_registration = isset($prop['registration']);
+ } else {
+ $fld_editcount = $fld_groups = $fld_registration = false;
+ }
+
+ $limit = $params['limit'];
+ $tables = $db->tableName('user');
+
+ if( !is_null( $params['from'] ) )
+ $this->addWhere( 'user_name >= ' . $db->addQuotes( self::keyToTitle( $params['from'] ) ) );
+
+ if( isset( $params['prefix'] ) )
+ $this->addWhere( 'user_name LIKE "' . $db->escapeLike( self::keyToTitle( $params['prefix'] ) ) . '%"' );
+
+ if (!is_null($params['group'])) {
+ // Filter only users that belong to a given group
+ $tblName = $db->tableName('user_groups');
+ $tables = "$tables INNER JOIN $tblName ug1 ON ug1.ug_user=user_id";
+ $this->addWhereFld('ug1.ug_group', $params['group']);
+ }
+
+ if ($fld_groups) {
+ // Show the groups the given users belong to
+ // request more than needed to avoid not getting all rows that belong to one user
+ $groupCount = count(User::getAllGroups());
+ $sqlLimit = $limit+$groupCount+1;
+
+ $tblName = $db->tableName('user_groups');
+ $tables = "$tables LEFT JOIN $tblName ug2 ON ug2.ug_user=user_id";
+ $this->addFields('ug2.ug_group ug_group2');
+ } else {
+ $sqlLimit = $limit+1;
+ }
+
+ if ($fld_registration)
+ $this->addFields('user_registration');
+
+ $this->addOption('LIMIT', $sqlLimit);
+ $this->addTables($tables);
+
+ $this->addFields('user_name');
+ $this->addFieldsIf('user_editcount', $fld_editcount);
+
+ $this->addOption('ORDER BY', 'user_name');
+
+ $res = $this->select(__METHOD__);
+
+ $data = array ();
+ $count = 0;
+ $lastUserData = false;
+ $lastUser = false;
+ $result = $this->getResult();
+
+ //
+ // This loop keeps track of the last entry.
+ // For each new row, if the new row is for different user then the last, the last entry is added to results.
+ // Otherwise, the group of the new row is appended to the last entry.
+ // The setContinue... is more complex because of this, and takes into account the higher sql limit
+ // to make sure all rows that belong to the same user are received.
+ //
+ while (true) {
+
+ $row = $db->fetchObject($res);
+ $count++;
+
+ if (!$row || $lastUser != $row->user_name) {
+ // Save the last pass's user data
+ if (is_array($lastUserData))
+ $data[] = $lastUserData;
+
+ // No more rows left
+ if (!$row)
+ break;
+
+ if ($count > $limit) {
+ // We've reached the one extra which shows that there are additional pages to be had. Stop here...
+ $this->setContinueEnumParameter('from', ApiQueryBase :: keyToTitle($row->user_name));
+ break;
+ }
+
+ // Record new user's data
+ $lastUser = $row->user_name;
+ $lastUserData = array( 'name' => $lastUser );
+ if ($fld_editcount)
+ $lastUserData['editcount'] = intval($row->user_editcount);
+ if ($fld_registration)
+ $lastUserData['registration'] = wfTimestamp(TS_ISO_8601, $row->user_registration);
+
+ }
+
+ if ($sqlLimit == $count) {
+ // BUG! database contains group name that User::getAllGroups() does not return
+ // TODO: should handle this more gracefully
+ ApiBase :: dieDebug(__METHOD__,
+ 'MediaWiki configuration error: the database contains more user groups than known to User::getAllGroups() function');
+ }
+
+ // Add user's group info
+ if ($fld_groups && !is_null($row->ug_group2)) {
+ $lastUserData['groups'][] = $row->ug_group2;
+ $result->setIndexedTagName($lastUserData['groups'], 'g');
+ }
+ }
+
+ $db->freeResult($res);
+
+ $result->setIndexedTagName($data, 'u');
+ $result->addValue('query', $this->getModuleName(), $data);
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'from' => null,
+ 'prefix' => null,
+ 'group' => array(
+ ApiBase :: PARAM_TYPE => User::getAllGroups()
+ ),
+ 'prop' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => array (
+ 'editcount',
+ 'groups',
+ 'registration',
+ )
+ ),
+ 'limit' => array (
+ ApiBase :: PARAM_DFLT => 10,
+ ApiBase :: PARAM_TYPE => 'limit',
+ ApiBase :: PARAM_MIN => 1,
+ ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+ )
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'from' => 'The user name to start enumerating from.',
+ 'prefix' => 'Search for all page titles that begin with this value.',
+ 'group' => 'Limit users to a given group name',
+ 'prop' => array(
+ 'What pieces of information to include.',
+ '`groups` property uses more server resources and may return fewer results than the limit.'),
+ 'limit' => 'How many total user names to return.',
+ );
+ }
+
+ protected function getDescription() {
+ return 'Enumerate all registered users';
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=query&list=allusers&aufrom=Y',
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
--- /dev/null
+<?php
+
+/*
+ * Created on Dec 1, 2007
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+/**
+ * A query action to return messages from site message cache
+ *
+ * @addtogroup API
+ */
+class ApiQueryAllmessages extends ApiQueryBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'am');
+ }
+
+ public function execute() {
+ global $wgMessageCache;
+ $params = $this->extractRequestParams();
+
+ //Determine which messages should we print
+ $messages_target = array();
+ if( $params['messages'] == '*' ) {
+ $wgMessageCache->loadAllMessages();
+ $message_names = array_keys( array_merge( Language::getMessagesFor( 'en' ), $wgMessageCache->getExtensionMessagesFor( 'en' ) ) );
+ sort( $message_names );
+ $messages_target = $message_names;
+ } else {
+ $messages_target = explode( '|', $params['messages'] );
+ }
+
+ //Filter messages
+ if( isset( $params['filter'] ) ) {
+ $messages_filtered = array();
+ foreach( $messages_target as $message ) {
+ if( strpos( $message, $params['filter'] ) !== false ) { //!== is used because filter can be at the beginnig of the string
+ $messages_filtered[] = $message;
+ }
+ }
+ $messages_target = $messages_filtered;
+ }
+
+ $wgMessageCache->disableTransform();
+
+ //Get all requested messages
+ $messages = array();
+ foreach( $messages_target as $message ) {
+ $message = trim( $message ); //Message list can be formatted like "msg1 | msg2 | msg3", so let's trim() it
+ $messages[$message] = wfMsg( $message );
+ }
+
+ //Print the result
+ $result = $this->getResult();
+ $messages_out = array();
+ foreach( $messages as $name => $value ) {
+ $message = array();
+ $message['name'] = $name;
+ $result->setContent( $message, $value );
+ $messages_out[] = $message;
+ }
+ $result->setIndexedTagName( $messages_out, 'message' );
+ $result->addValue( null, $this->getModuleName(), $messages_out );
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'messages' => array (
+ ApiBase :: PARAM_DFLT => '*',
+ ),
+ 'filter' => array(),
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'messages' => 'Which messages to output. "*" means all messages',
+ 'filter' => 'Return only messages that contains specified string',
+ );
+ }
+
+ protected function getDescription() {
+ return 'Return messages from this site.';
+ }
+
+ protected function getExamples() {
+ return array(
+ 'api.php?action=query&meta=allmessages&amfilter=ipb-',
+ 'api.php?action=query&meta=allmessages&ammessages=august|mainpage',
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
--- /dev/null
+<?php
+
+/*
+ * Created on Sep 25, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+/**
+ * Query module to enumerate all available pages.
+ *
+ * @addtogroup API
+ */
+class ApiQueryAllpages extends ApiQueryGeneratorBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'ap');
+ }
+
+ public function execute() {
+ $this->run();
+ }
+
+ public function executeGenerator($resultPageSet) {
+ if ($resultPageSet->isResolvingRedirects())
+ $this->dieUsage('Use "gapfilterredir=nonredirects" option instead of "redirects" when using allpages as a generator', 'params');
+
+ $this->run($resultPageSet);
+ }
+
+ private function run($resultPageSet = null) {
+
+ $db = $this->getDB();
+
+ $params = $this->extractRequestParams();
+
+ // Page filters
+ if (!$this->addWhereIf('page_is_redirect = 1', $params['filterredir'] === 'redirects'))
+ $this->addWhereIf('page_is_redirect = 0', $params['filterredir'] === 'nonredirects');
+ $this->addWhereFld('page_namespace', $params['namespace']);
+ if (!is_null($params['from']))
+ $this->addWhere('page_title>=' . $db->addQuotes(ApiQueryBase :: titleToKey($params['from'])));
+ if (isset ($params['prefix']))
+ $this->addWhere("page_title LIKE '" . $db->escapeLike(ApiQueryBase :: titleToKey($params['prefix'])) . "%'");
+
+ $forceNameTitleIndex = true;
+ if (isset ($params['minsize'])) {
+ $this->addWhere('page_len>=' . intval($params['minsize']));
+ $forceNameTitleIndex = false;
+ }
+
+ if (isset ($params['maxsize'])) {
+ $this->addWhere('page_len<=' . intval($params['maxsize']));
+ $forceNameTitleIndex = false;
+ }
+
+ // Page protection filtering
+ if (isset ($params['prtype'])) {
+ $this->addTables('page_restrictions');
+ $this->addWhere('page_id=pr_page');
+ $this->addWhere('pr_expiry>' . $db->addQuotes($db->timestamp()));
+ $this->addWhereFld('pr_type', $params['prtype']);
+
+ $prlevel = $params['prlevel'];
+ if (!is_null($prlevel) && $prlevel != '' && $prlevel != '*')
+ $this->addWhereFld('pr_level', $prlevel);
+
+ $this->addOption('DISTINCT');
+
+ $forceNameTitleIndex = false;
+
+ } else if (isset ($params['prlevel'])) {
+ $this->dieUsage('prlevel may not be used without prtype', 'params');
+ }
+
+ $this->addTables('page');
+ if ($forceNameTitleIndex)
+ $this->addOption('USE INDEX', 'name_title');
+
+
+ if (is_null($resultPageSet)) {
+ $this->addFields(array (
+ 'page_id',
+ 'page_namespace',
+ 'page_title'
+ ));
+ } else {
+ $this->addFields($resultPageSet->getPageTableFields());
+ }
+
+ $limit = $params['limit'];
+ $this->addOption('LIMIT', $limit+1);
+ $this->addOption('ORDER BY', 'page_namespace, page_title' .
+ ($params['dir'] == 'ZtoA' ? ' DESC' : ''));
+
+ $res = $this->select(__METHOD__);
+
+ $data = array ();
+ $count = 0;
+ while ($row = $db->fetchObject($res)) {
+ if (++ $count > $limit) {
+ // We've reached the one extra which shows that there are additional pages to be had. Stop here...
+ // TODO: Security issue - if the user has no right to view next title, it will still be shown
+ $this->setContinueEnumParameter('from', ApiQueryBase :: keyToTitle($row->page_title));
+ break;
+ }
+
+ if (is_null($resultPageSet)) {
+ $title = Title :: makeTitle($row->page_namespace, $row->page_title);
+ $data[] = array(
+ 'pageid' => intval($row->page_id),
+ 'ns' => intval($title->getNamespace()),
+ 'title' => $title->getPrefixedText());
+ } else {
+ $resultPageSet->processDbRow($row);
+ }
+ }
+ $db->freeResult($res);
+
+ if (is_null($resultPageSet)) {
+ $result = $this->getResult();
+ $result->setIndexedTagName($data, 'p');
+ $result->addValue('query', $this->getModuleName(), $data);
+ }
+ }
+
+ protected function getAllowedParams() {
+ global $wgRestrictionTypes, $wgRestrictionLevels;
+
+ return array (
+ 'from' => null,
+ 'prefix' => null,
+ 'namespace' => array (
+ ApiBase :: PARAM_DFLT => 0,
+ ApiBase :: PARAM_TYPE => 'namespace',
+ ),
+ 'filterredir' => array (
+ ApiBase :: PARAM_DFLT => 'all',
+ ApiBase :: PARAM_TYPE => array (
+ 'all',
+ 'redirects',
+ 'nonredirects'
+ )
+ ),
+ 'minsize' => array (
+ ApiBase :: PARAM_TYPE => 'integer',
+ ),
+ 'maxsize' => array (
+ ApiBase :: PARAM_TYPE => 'integer',
+ ),
+ 'prtype' => array (
+ ApiBase :: PARAM_TYPE => $wgRestrictionTypes,
+ ApiBase :: PARAM_ISMULTI => true
+ ),
+ 'prlevel' => array (
+ ApiBase :: PARAM_TYPE => $wgRestrictionLevels,
+ ApiBase :: PARAM_ISMULTI => true
+ ),
+ 'limit' => array (
+ ApiBase :: PARAM_DFLT => 10,
+ ApiBase :: PARAM_TYPE => 'limit',
+ ApiBase :: PARAM_MIN => 1,
+ ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+ ),
+ 'dir' => array (
+ ApiBase :: PARAM_DFLT => 'AtoZ',
+ ApiBase :: PARAM_TYPE => array (
+ 'AtoZ',
+ 'ZtoA'
+ )
+ )
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'from' => 'The page title to start enumerating from.',
+ 'prefix' => 'Search for all page titles that begin with this value.',
+ 'namespace' => 'The namespace to enumerate.',
+ 'filterredir' => 'Which pages to list.',
+ 'dir' => 'The direction in which to list',
+ 'minsize' => 'Limit to pages with at least this many bytes',
+ 'maxsize' => 'Limit to pages with at most this many bytes',
+ 'prtype' => 'Limit to protected pages only',
+ 'prlevel' => 'The protection level (must be used with apprtype= parameter)',
+ 'limit' => 'How many total pages to return.'
+ );
+ }
+
+ protected function getDescription() {
+ return 'Enumerate all pages sequentially in a given namespace';
+ }
+
+ protected function getExamples() {
+ return array (
+ 'Simple Use',
+ ' Show a list of pages starting at the letter "B"',
+ ' api.php?action=query&list=allpages&apfrom=B',
+ 'Using as Generator',
+ ' Show info about 4 pages starting at the letter "T"',
+ ' api.php?action=query&generator=allpages&gaplimit=4&gapfrom=T&prop=info',
+ ' Show content of first 2 non-redirect pages begining at "Re"',
+ ' api.php?action=query&generator=allpages&gaplimit=2&gapfilterredir=nonredirects&gapfrom=Re&prop=revisions&rvprop=content'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+
--- /dev/null
+<?php
+
+/*
+ * Created on Oct 16, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ("ApiQueryBase.php");
+}
+
+/**
+ * This is three-in-one module to query:
+ * * backlinks - links pointing to the given page,
+ * * embeddedin - what pages transclude the given page within themselves,
+ * * imageusage - what pages use the given image
+ *
+ * @addtogroup API
+ */
+class ApiQueryBacklinks extends ApiQueryGeneratorBase {
+
+ private $params, $rootTitle, $contRedirs, $contLevel, $contTitle, $contID;
+
+ // output element name, database column field prefix, database table
+ private $backlinksSettings = array (
+ 'backlinks' => array (
+ 'code' => 'bl',
+ 'prefix' => 'pl',
+ 'linktbl' => 'pagelinks'
+ ),
+ 'embeddedin' => array (
+ 'code' => 'ei',
+ 'prefix' => 'tl',
+ 'linktbl' => 'templatelinks'
+ ),
+ 'imageusage' => array (
+ 'code' => 'iu',
+ 'prefix' => 'il',
+ 'linktbl' => 'imagelinks'
+ )
+ );
+
+ public function __construct($query, $moduleName) {
+ $code = $prefix = $linktbl = null;
+ extract($this->backlinksSettings[$moduleName]);
+
+ parent :: __construct($query, $moduleName, $code);
+ $this->bl_ns = $prefix . '_namespace';
+ $this->bl_from = $prefix . '_from';
+ $this->bl_tables = array (
+ $linktbl,
+ 'page'
+ );
+ $this->bl_code = $code;
+
+ $this->hasNS = $moduleName !== 'imageusage';
+ if ($this->hasNS) {
+ $this->bl_title = $prefix . '_title';
+ $this->bl_sort = "{$this->bl_ns}, {$this->bl_title}, {$this->bl_from}";
+ $this->bl_fields = array (
+ $this->bl_ns,
+ $this->bl_title
+ );
+ } else {
+ $this->bl_title = $prefix . '_to';
+ $this->bl_sort = "{$this->bl_title}, {$this->bl_from}";
+ $this->bl_fields = array (
+ $this->bl_title
+ );
+ }
+ }
+
+ public function execute() {
+ $this->run();
+ }
+
+ public function executeGenerator($resultPageSet) {
+ $this->run($resultPageSet);
+ }
+
+ private function run($resultPageSet = null) {
+ $this->params = $this->extractRequestParams();
+
+ $redirect = $this->params['redirect'];
+ if ($redirect)
+ $this->dieDebug('Redirect has not been implemented', 'notimplemented');
+
+ $this->processContinue();
+
+ $this->addFields($this->bl_fields);
+ if (is_null($resultPageSet))
+ $this->addFields(array (
+ 'page_id',
+ 'page_namespace',
+ 'page_title'
+ ));
+ else
+ $this->addFields($resultPageSet->getPageTableFields()); // will include page_id
+
+ $this->addTables($this->bl_tables);
+ $this->addWhere($this->bl_from . '=page_id');
+
+ if ($this->hasNS)
+ $this->addWhereFld($this->bl_ns, $this->rootTitle->getNamespace());
+ $this->addWhereFld($this->bl_title, $this->rootTitle->getDBkey());
+ $this->addWhereFld('page_namespace', $this->params['namespace']);
+
+ if($this->params['filterredir'] == 'redirects')
+ $this->addWhereFld('page_is_redirect', 1);
+ if($this->params['filterredir'] == 'nonredirects')
+ $this->addWhereFld('page_is_redirect', 0);
+
+ $limit = $this->params['limit'];
+ $this->addOption('LIMIT', $limit +1);
+ $this->addOption('ORDER BY', $this->bl_sort);
+
+ $db = $this->getDB();
+ if (!is_null($this->params['continue'])) {
+ $plfrm = intval($this->contID);
+ if ($this->contLevel == 0) {
+ // For the first level, there is only one target title, so no need for complex filtering
+ $this->addWhere($this->bl_from . '>=' . $plfrm);
+ } else {
+ $ns = $this->contTitle->getNamespace();
+ $t = $db->addQuotes($this->contTitle->getDBkey());
+ $whereWithoutNS = "{$this->bl_title}>$t OR ({$this->bl_title}=$t AND {$this->bl_from}>=$plfrm))";
+
+ if ($this->hasNS)
+ $this->addWhere("{$this->bl_ns}>$ns OR ({$this->bl_ns}=$ns AND ($whereWithoutNS)");
+ else
+ $this->addWhere($whereWithoutNS);
+ }
+ }
+
+ $res = $this->select(__METHOD__);
+
+ $count = 0;
+ $data = array ();
+ while ($row = $db->fetchObject($res)) {
+ if (++ $count > $limit) {
+ // We've reached the one extra which shows that there are additional pages to be had. Stop here...
+ if ($redirect) {
+ $ns = $row-> { $this->bl_ns };
+ $t = $row-> { $this->bl_title };
+ $continue = $this->getContinueRedirStr(false, 0, $ns, $t, $row->page_id);
+ } else
+ $continue = $this->getContinueStr($row->page_id);
+ // TODO: Security issue - if the user has no right to view next title, it will still be shown
+ $this->setContinueEnumParameter('continue', $continue);
+ break;
+ }
+
+ if (is_null($resultPageSet)) {
+ $vals = $this->extractRowInfo($row);
+ if ($vals)
+ $data[] = $vals;
+ } else {
+ $resultPageSet->processDbRow($row);
+ }
+ }
+ $db->freeResult($res);
+
+ if (is_null($resultPageSet)) {
+ $result = $this->getResult();
+ $result->setIndexedTagName($data, $this->bl_code);
+ $result->addValue('query', $this->getModuleName(), $data);
+ }
+ }
+
+ private function extractRowInfo($row) {
+
+ $vals = array();
+ $vals['pageid'] = intval($row->page_id);
+ ApiQueryBase :: addTitleInfo($vals, Title :: makeTitle($row->page_namespace, $row->page_title));
+
+ return $vals;
+ }
+
+ protected function processContinue() {
+ $pageSet = $this->getPageSet();
+ $count = $pageSet->getTitleCount();
+
+ if (!is_null($this->params['continue'])) {
+ $this->parseContinueParam();
+
+ // Skip all completed links
+
+ } else {
+ $title = $this->params['title'];
+ if (!is_null($title)) {
+ $this->rootTitle = Title :: newFromText($title);
+ } else { // This case is obsolete. Will support this for a while
+ if ($count !== 1)
+ $this->dieUsage("The {$this->getModuleName()} query requires one title to start", 'bad_title_count');
+ $this->rootTitle = current($pageSet->getTitles()); // only one title there
+ $this->setWarning('Using titles parameter is obsolete for this list. Use ' . $this->encodeParamName('title') . ' instead.');
+ }
+ }
+
+ // only image titles are allowed for the root
+ if (!$this->hasNS && $this->rootTitle->getNamespace() !== NS_IMAGE)
+ $this->dieUsage("The title for {$this->getModuleName()} query must be an image", 'bad_image_title');
+ }
+
+ protected function parseContinueParam() {
+ $continueList = explode('|', $this->params['continue']);
+ if ($this->params['redirect']) {
+ //
+ // expected redirect-mode parameter:
+ // ns|db_key|step|level|ns|db_key|id
+ // ns+db_key -- the root title
+ // step = 1 or 2 - which step to continue from - 1-titles, 2-redirects
+ // level -- how many levels to follow before starting enumerating.
+ // if level > 0 -- ns+title to continue from, otherwise skip these
+ // id = last page_id to continue from
+ //
+ if (count($continueList) > 4) {
+ $rootNs = intval($continueList[0]);
+ if (($rootNs !== 0 || $continueList[0] === '0') && !empty ($continueList[1])) {
+ $this->rootTitle = Title :: makeTitleSafe($rootNs, $continueList[1]);
+ if ($this->rootTitle) {
+
+ $step = intval($continueList[2]);
+ if ($step === 1 || $step === 2) {
+ $this->contRedirs = ($step === 2);
+
+ $level = intval($continueList[3]);
+ if ($level !== 0 || $continueList[3] === '0') {
+ $this->contLevel = $level;
+
+ if ($level === 0) {
+ if (count($continueList) === 5) {
+ $contID = intval($continueList[4]);
+ if ($contID !== 0 || $continueList[4] === '0') {
+ $this->contID = $contID;
+ return; // done
+ }
+ }
+ } else {
+ if (count($continueList) === 7) {
+ $contNs = intval($continueList[4]);
+ if (($contNs !== 0 || $continueList[4] === '0') && !empty ($continueList[5])) {
+ $this->contTitle = Title :: makeTitleSafe($contNs, $continueList[5]);
+
+ $contID = intval($continueList[6]);
+ if ($contID !== 0 || $continueList[6] === '0') {
+ $this->contID = $contID;
+ return; // done
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } else {
+ //
+ // expected non-redirect-mode parameter:
+ // ns|db_key|id
+ // ns+db_key -- the root title
+ // id = last page_id to continue from
+ //
+ if (count($continueList) === 3) {
+ $rootNs = intval($continueList[0]);
+ if (($rootNs !== 0 || $continueList[0] === '0') && !empty ($continueList[1])) {
+ $this->rootTitle = Title :: makeTitleSafe($rootNs, $continueList[1]);
+ if ($this->rootTitle) {
+
+ $contID = intval($continueList[2]);
+ if ($contID !== 0) {
+ $this->contID = $contID;
+ return; // done
+ }
+ }
+ }
+ }
+ }
+
+ $this->dieUsage("Invalid continue param. You should pass the original value returned by the previous query", "_badcontinue");
+ }
+
+ protected function getContinueStr($lastPageID) {
+ return $this->rootTitle->getNamespace() .
+ '|' . $this->rootTitle->getDBkey() .
+ '|' . $lastPageID;
+ }
+
+ protected function getContinueRedirStr($isRedirPhase, $level, $ns, $title, $lastPageID) {
+ return $this->rootTitle->getNamespace() .
+ '|' . $this->rootTitle->getDBkey() .
+ '|' . ($isRedirPhase ? 1 : 2) .
+ '|' . $level .
+ ($level > 0 ? ('|' . $ns . '|' . $title) : '') .
+ '|' . $lastPageID;
+ }
+
+ protected function getAllowedParams() {
+
+ return array (
+ 'title' => null,
+ 'continue' => null,
+ 'namespace' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => 'namespace'
+ ),
+ 'filterredir' => array(
+ ApiBase :: PARAM_DFLT => 'all',
+ ApiBase :: PARAM_TYPE => array(
+ 'all',
+ 'redirects',
+ 'nonredirects'
+ )
+ ),
+ 'redirect' => false,
+ 'limit' => array (
+ ApiBase :: PARAM_DFLT => 10,
+ ApiBase :: PARAM_TYPE => 'limit',
+ ApiBase :: PARAM_MIN => 1,
+ ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+ )
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'title' => 'Title to search. If null, titles= parameter will be used instead, but will be obsolete soon.',
+ 'continue' => 'When more results are available, use this to continue.',
+ 'namespace' => 'The namespace to enumerate.',
+ 'filterredir' => 'How to filter for redirects',
+ 'redirect' => 'If linking page is a redirect, find all pages that link to that redirect (not implemented)',
+ 'limit' => 'How many total pages to return.'
+ );
+ }
+
+ protected function getDescription() {
+ switch ($this->getModuleName()) {
+ case 'backlinks' :
+ return 'Find all pages that link to the given page';
+ case 'embeddedin' :
+ return 'Find all pages that embed (transclude) the given title';
+ case 'imageusage' :
+ return 'Find all pages that use the given image title.';
+ default :
+ ApiBase :: dieDebug(__METHOD__, 'Unknown module name');
+ }
+ }
+
+ protected function getExamples() {
+ static $examples = array (
+ 'backlinks' => array (
+ "api.php?action=query&list=backlinks&bltitle=Main%20Page",
+ "api.php?action=query&generator=backlinks&gbltitle=Main%20Page&prop=info"
+ ),
+ 'embeddedin' => array (
+ "api.php?action=query&list=embeddedin&eititle=Template:Stub",
+ "api.php?action=query&generator=embeddedin&geititle=Template:Stub&prop=info"
+ ),
+ 'imageusage' => array (
+ "api.php?action=query&list=imageusage&iutitle=Image:Albert%20Einstein%20Head.jpg",
+ "api.php?action=query&generator=imageusage&giutitle=Image:Albert%20Einstein%20Head.jpg&prop=info"
+ )
+ );
+
+ return $examples[$this->getModuleName()];
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+
--- /dev/null
+<?php
+
+/*
+ * Created on Sep 7, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiBase.php');
+}
+
+/**
+ * This is a base class for all Query modules.
+ * It provides some common functionality such as constructing various SQL queries.
+ *
+ * @addtogroup API
+ */
+abstract class ApiQueryBase extends ApiBase {
+
+ private $mQueryModule, $mDb, $tables, $where, $fields, $options;
+
+ public function __construct($query, $moduleName, $paramPrefix = '') {
+ parent :: __construct($query->getMain(), $moduleName, $paramPrefix);
+ $this->mQueryModule = $query;
+ $this->mDb = null;
+ $this->resetQueryParams();
+ }
+
+ protected function resetQueryParams() {
+ $this->tables = array ();
+ $this->where = array ();
+ $this->fields = array ();
+ $this->options = array ();
+ }
+
+ protected function addTables($tables, $alias = null) {
+ if (is_array($tables)) {
+ if (!is_null($alias))
+ ApiBase :: dieDebug(__METHOD__, 'Multiple table aliases not supported');
+ $this->tables = array_merge($this->tables, $tables);
+ } else {
+ if (!is_null($alias))
+ $tables = $this->getDB()->tableName($tables) . ' ' . $alias;
+ $this->tables[] = $tables;
+ }
+ }
+
+ protected function addFields($value) {
+ if (is_array($value))
+ $this->fields = array_merge($this->fields, $value);
+ else
+ $this->fields[] = $value;
+ }
+
+ protected function addFieldsIf($value, $condition) {
+ if ($condition) {
+ $this->addFields($value);
+ return true;
+ }
+ return false;
+ }
+
+ protected function addWhere($value) {
+ if (is_array($value))
+ $this->where = array_merge($this->where, $value);
+ else
+ $this->where[] = $value;
+ }
+
+ protected function addWhereIf($value, $condition) {
+ if ($condition) {
+ $this->addWhere($value);
+ return true;
+ }
+ return false;
+ }
+
+ protected function addWhereFld($field, $value) {
+ if (!is_null($value))
+ $this->where[$field] = $value;
+ }
+
+ protected function addWhereRange($field, $dir, $start, $end) {
+ $isDirNewer = ($dir === 'newer');
+ $after = ($isDirNewer ? '>=' : '<=');
+ $before = ($isDirNewer ? '<=' : '>=');
+ $db = $this->getDB();
+
+ if (!is_null($start))
+ $this->addWhere($field . $after . $db->addQuotes($start));
+
+ if (!is_null($end))
+ $this->addWhere($field . $before . $db->addQuotes($end));
+
+ $this->addOption('ORDER BY', $field . ($isDirNewer ? '' : ' DESC'));
+ }
+
+ protected function addOption($name, $value = null) {
+ if (is_null($value))
+ $this->options[] = $name;
+ else
+ $this->options[$name] = $value;
+ }
+
+ protected function select($method) {
+
+ // getDB has its own profileDBIn/Out calls
+ $db = $this->getDB();
+
+ $this->profileDBIn();
+ $res = $db->select($this->tables, $this->fields, $this->where, $method, $this->options);
+ $this->profileDBOut();
+
+ return $res;
+ }
+
+ public static function addTitleInfo(&$arr, $title, $prefix='') {
+ $arr[$prefix . 'ns'] = intval($title->getNamespace());
+ $arr[$prefix . 'title'] = $title->getPrefixedText();
+ }
+
+ /**
+ * Override this method to request extra fields from the pageSet
+ * using $pageSet->requestField('fieldName')
+ */
+ public function requestExtraData($pageSet) {
+ }
+
+ /**
+ * Get the main Query module
+ */
+ public function getQuery() {
+ return $this->mQueryModule;
+ }
+
+ /**
+ * Add sub-element under the page element with the given pageId.
+ */
+ protected function addPageSubItems($pageId, $data) {
+ $result = $this->getResult();
+ $result->setIndexedTagName($data, $this->getModulePrefix());
+ $result->addValue(array ('query', 'pages', intval($pageId)),
+ $this->getModuleName(),
+ $data);
+ }
+
+ protected function setContinueEnumParameter($paramName, $paramValue) {
+
+ $paramName = $this->encodeParamName($paramName);
+ $msg = array( $paramName => $paramValue );
+
+// This is an alternative continue format as a part of the URL string
+// ApiResult :: setContent($msg, $paramName . '=' . urlencode($paramValue));
+
+ $this->getResult()->addValue('query-continue', $this->getModuleName(), $msg);
+ }
+
+ /**
+ * Get the Query database connection (readonly)
+ */
+ protected function getDB() {
+ if (is_null($this->mDb))
+ $this->mDb = $this->getQuery()->getDB();
+ return $this->mDb;
+ }
+
+ /**
+ * Selects the query database connection with the given name.
+ * If no such connection has been requested before, it will be created.
+ * Subsequent calls with the same $name will return the same connection
+ * as the first, regardless of $db or $groups new values.
+ */
+ public function selectNamedDB($name, $db, $groups) {
+ $this->mDb = $this->getQuery()->getNamedDB($name, $db, $groups);
+ }
+
+ /**
+ * Get the PageSet object to work on
+ * @return ApiPageSet data
+ */
+ protected function getPageSet() {
+ return $this->getQuery()->getPageSet();
+ }
+
+ /**
+ * This is a very simplistic utility function
+ * to convert a non-namespaced title string to a db key.
+ * It will replace all ' ' with '_'
+ */
+ public static function titleToKey($title) {
+ return str_replace(' ', '_', $title);
+ }
+
+ public static function keyToTitle($key) {
+ return str_replace('_', ' ', $key);
+ }
+
+ public function getTokenFlag($tokenArr, $action) {
+ if (in_array($action, $tokenArr)) {
+ global $wgUser;
+ if ($wgUser->isAllowed($action))
+ return true;
+ else
+ $this->dieUsage("Action '$action' is not allowed for the current user", 'permissiondenied');
+ }
+ return false;
+ }
+
+ public static function getBaseVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+
+/**
+ * @addtogroup API
+ */
+abstract class ApiQueryGeneratorBase extends ApiQueryBase {
+
+ private $mIsGenerator;
+
+ public function __construct($query, $moduleName, $paramPrefix = '') {
+ parent :: __construct($query, $moduleName, $paramPrefix);
+ $this->mIsGenerator = false;
+ }
+
+ public function setGeneratorMode() {
+ $this->mIsGenerator = true;
+ }
+
+ /**
+ * Overrides base class to prepend 'g' to every generator parameter
+ */
+ public function encodeParamName($paramName) {
+ if ($this->mIsGenerator)
+ return 'g' . parent :: encodeParamName($paramName);
+ else
+ return parent :: encodeParamName($paramName);
+ }
+
+ /**
+ * Execute this module as a generator
+ * @param $resultPageSet PageSet: All output should be appended to this object
+ */
+ public abstract function executeGenerator($resultPageSet);
+}
+
--- /dev/null
+<?php
+
+/*
+ * Created on Sep 10, 2007
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+/**
+ * Query module to enumerate all available pages.
+ *
+ * @addtogroup API
+ */
+class ApiQueryBlocks extends ApiQueryBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'bk');
+ }
+
+ public function execute() {
+ $this->run();
+ }
+
+ private function run() {
+ global $wgUser;
+
+ $params = $this->extractRequestParams();
+ $prop = array_flip($params['prop']);
+ $fld_id = isset($prop['id']);
+ $fld_user = isset($prop['user']);
+ $fld_by = isset($prop['by']);
+ $fld_timestamp = isset($prop['timestamp']);
+ $fld_expiry = isset($prop['expiry']);
+ $fld_reason = isset($prop['reason']);
+ $fld_range = isset($prop['range']);
+ $fld_flags = isset($prop['flags']);
+
+ $result = $this->getResult();
+ $pageSet = $this->getPageSet();
+ $titles = $pageSet->getTitles();
+ $data = array();
+
+ $this->addTables('ipblocks');
+ if($fld_id)
+ $this->addFields('ipb_id');
+ if($fld_user)
+ $this->addFields(array('ipb_address', 'ipb_user'));
+ if($fld_by)
+ {
+ $this->addTables('user');
+ $this->addFields(array('ipb_by', 'user_name'));
+ $this->addWhere('user_id = ipb_by');
+ }
+ if($fld_timestamp)
+ $this->addFields('ipb_timestamp');
+ if($fld_expiry)
+ $this->addFields('ipb_expiry');
+ if($fld_reason)
+ $this->addFields('ipb_reason');
+ if($fld_range)
+ $this->addFields(array('ipb_range_start', 'ipb_range_end'));
+ if($fld_flags)
+ $this->addFields(array('ipb_auto', 'ipb_anon_only', 'ipb_create_account', 'ipb_enable_autoblock', 'ipb_block_email', 'ipb_deleted'));
+
+ $this->addOption('LIMIT', $params['limit'] + 1);
+ $this->addWhereRange('ipb_timestamp', $params['dir'], $params['start'], $params['end']);
+ if(isset($params['ids']))
+ $this->addWhere(array('ipb_id' => $params['ids']));
+ if(isset($params['users']))
+ $this->addWhere(array('ipb_address' => $params['users']));
+ if(!$wgUser->isAllowed('oversight'))
+ $this->addWhere(array('ipb_deleted' => 0));
+
+ // Purge expired entries on one in every 10 queries
+ if(!mt_rand(0, 10))
+ Block::purgeExpired();
+
+ $res = $this->select(__METHOD__);
+ $db = wfGetDB();
+
+ $count = 0;
+ while($row = $db->fetchObject($res))
+ {
+ if($count++ == $params['limit'])
+ {
+ // We've had enough
+ $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->ipb_timestamp));
+ break;
+ }
+ $block = array();
+ if($fld_id)
+ $block['id'] = $row->ipb_id;
+ if($fld_user)
+ {
+ $block['user'] = $row->ipb_address;
+ $block['userid'] = $row->ipb_user;
+ }
+ if($fld_by)
+ {
+ $block['by'] = $row->user_name;
+ $block['byuserid'] = $row->ipb_by;
+ }
+ if($fld_timestamp)
+ $block['timestamp'] = wfTimestamp(TS_ISO_8601, $row->ipb_timestamp);
+ if($fld_expiry)
+ $block['expiry'] = Block::decodeExpiry($row->ipb_expiry, TS_ISO_8601);
+ if($fld_reason)
+ $block['reason'] = $row->ipb_reason;
+ if($fld_range)
+ {
+ $block['rangestart'] = $this->convertHexIP($row->ipb_range_start);
+ $block['rangeend'] = $this->convertHexIP($row->ipb_range_end);
+ }
+ if($fld_flags)
+ {
+ // For clarity, these flags use the same names as their action=block counterparts
+ if($row->ipb_auto)
+ $block['automatic'] = '';
+ if($row->ipb_anon_only)
+ $block['anononly'] = '';
+ if($row->ipb_create_account)
+ $block['nocreate'] = '';
+ if($row->ipb_enable_autoblock)
+ $block['autoblock'] = '';
+ if($row->ipb_block_email)
+ $block['noemail'] = '';
+ if($row->ipb_deleted)
+ $block['hidden'] = '';
+ }
+ $data[] = $block;
+ }
+ $result->setIndexedTagName($data, 'block');
+ $result->addValue('query', $this->getModuleName(), $data);
+ }
+
+ protected function convertHexIP($ip)
+ {
+ // Converts a hexadecimal IP to nnn.nnn.nnn.nnn format
+ $dec = wfBaseConvert($ip, 16, 10);
+ $parts[0] = (int)($dec / (256*256*256));
+ $dec %= 256*256*256;
+ $parts[1] = (int)($dec / (256*256));
+ $dec %= 256*256;
+ $parts[2] = (int)($dec / 256);
+ $parts[3] = $dec % 256;
+ return implode('.', $parts);
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'start' => array(
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'end' => array(
+ ApiBase :: PARAM_TYPE => 'timestamp',
+ ),
+ 'dir' => array(
+ ApiBase :: PARAM_TYPE => array(
+ 'newer',
+ 'older'
+ ),
+ ApiBase :: PARAM_DFLT => 'older'
+ ),
+ 'ids' => array(
+ ApiBase :: PARAM_TYPE => 'integer',
+ ApiBase :: PARAM_ISMULTI => true
+ ),
+ 'users' => array(
+ ApiBase :: PARAM_ISMULTI => true
+ ),
+ 'limit' => array(
+ ApiBase :: PARAM_DFLT => 10,
+ ApiBase :: PARAM_TYPE => 'limit',
+ ApiBase :: PARAM_MIN => 1,
+ ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+ ),
+ 'prop' => array(
+ ApiBase :: PARAM_DFLT => 'id|user|by|timestamp|expiry|reason|flags',
+ ApiBase :: PARAM_TYPE => array(
+ 'id',
+ 'user',
+ 'by',
+ 'timestamp',
+ 'expiry',
+ 'reason',
+ 'range',
+ 'flags'
+ ),
+ ApiBase :: PARAM_ISMULTI => true
+ )
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'start' => 'The timestamp to start enumerating from',
+ 'end' => 'The timestamp to stop enumerating at',
+ 'dir' => 'The direction in which to enumerate',
+ 'ids' => 'Pipe-separated list of block IDs to list (optional)',
+ 'users' => 'Pipe-separated list of users to search for (optional)',
+ 'limit' => 'The maximum amount of blocks to list',
+ 'prop' => 'Which properties to get',
+ );
+ }
+
+ protected function getDescription() {
+ return 'List all blocked users and IP addresses.';
+ }
+
+ protected function getExamples() {
+ return array (
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
--- /dev/null
+<?php
+
+/*
+ * Created on May 13, 2007
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ("ApiQueryBase.php");
+}
+
+/**
+ * A query module to enumerate categories the set of pages belong to.
+ *
+ * @addtogroup API
+ */
+class ApiQueryCategories extends ApiQueryGeneratorBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'cl');
+ }
+
+ public function execute() {
+ $this->run();
+ }
+
+ public function executeGenerator($resultPageSet) {
+ $this->run($resultPageSet);
+ }
+
+ private function run($resultPageSet = null) {
+
+ if ($this->getPageSet()->getGoodTitleCount() == 0)
+ return; // nothing to do
+
+ $params = $this->extractRequestParams();
+ $prop = $params['prop'];
+
+ $this->addFields(array (
+ 'cl_from',
+ 'cl_to'
+ ));
+
+ $fld_sortkey = false;
+ if (!is_null($prop)) {
+ foreach($prop as $p) {
+ switch ($p) {
+ case 'sortkey':
+ $this->addFields('cl_sortkey');
+ $fld_sortkey = true;
+ break;
+ default :
+ ApiBase :: dieDebug(__METHOD__, "Unknown prop=$p");
+ }
+ }
+ }
+
+ $this->addTables('categorylinks');
+ $this->addWhereFld('cl_from', array_keys($this->getPageSet()->getGoodTitles()));
+ $this->addOption('ORDER BY', "cl_from, cl_to");
+
+ $db = $this->getDB();
+ $res = $this->select(__METHOD__);
+
+ if (is_null($resultPageSet)) {
+
+ $data = array();
+ $lastId = 0; // database has no ID 0
+ while ($row = $db->fetchObject($res)) {
+ if ($lastId != $row->cl_from) {
+ if($lastId != 0) {
+ $this->addPageSubItems($lastId, $data);
+ $data = array();
+ }
+ $lastId = $row->cl_from;
+ }
+
+ $title = Title :: makeTitle(NS_CATEGORY, $row->cl_to);
+
+ $vals = array();
+ ApiQueryBase :: addTitleInfo($vals, $title);
+ if ($fld_sortkey)
+ $vals['sortkey'] = $row->cl_sortkey;
+
+ $data[] = $vals;
+ }
+
+ if($lastId != 0) {
+ $this->addPageSubItems($lastId, $data);
+ }
+
+ } else {
+
+ $titles = array();
+ while ($row = $db->fetchObject($res)) {
+ $titles[] = Title :: makeTitle(NS_CATEGORY, $row->cl_to);
+ }
+ $resultPageSet->populateFromTitles($titles);
+ }
+
+ $db->freeResult($res);
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'prop' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => array (
+ 'sortkey',
+ )
+ )
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'prop' => 'Which additional properties to get for each category.',
+ );
+ }
+
+ protected function getDescription() {
+ return 'List all categories the page(s) belong to';
+ }
+
+ protected function getExamples() {
+ return array (
+ "Get a list of categories [[Albert Einstein]] belongs to:",
+ " api.php?action=query&prop=categories&titles=Albert%20Einstein",
+ "Get information about all categories used in the [[Albert Einstein]]:",
+ " api.php?action=query&generator=categories&titles=Albert%20Einstein&prop=info"
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+
--- /dev/null
+<?php
+
+/*
+ * Created on June 14, 2007
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ("ApiQueryBase.php");
+}
+
+/**
+ * A query module to enumerate pages that belong to a category.
+ *
+ * @addtogroup API
+ */
+class ApiQueryCategoryMembers extends ApiQueryGeneratorBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'cm');
+ }
+
+ public function execute() {
+ $this->run();
+ }
+
+ public function executeGenerator($resultPageSet) {
+ $this->run($resultPageSet);
+ }
+
+ private function run($resultPageSet = null) {
+
+ $params = $this->extractRequestParams();
+
+ $category = $params['category'];
+ if (is_null($category))
+ $this->dieUsage("Category parameter is required", 'param_category');
+ $categoryTitle = Title::makeTitleSafe( NS_CATEGORY, $category );
+ if ( is_null( $categoryTitle ) )
+ $this->dieUsage("Category name $category is not valid", 'param_category');
+
+ $prop = array_flip($params['prop']);
+ $fld_ids = isset($prop['ids']);
+ $fld_title = isset($prop['title']);
+ $fld_sortkey = isset($prop['sortkey']);
+ $fld_timestamp = isset($prop['timestamp']);
+
+ if (is_null($resultPageSet)) {
+ $this->addFields(array('cl_from', 'cl_sortkey', 'page_namespace', 'page_title'));
+ $this->addFieldsIf('page_id', $fld_ids);
+ } else {
+ $this->addFields($resultPageSet->getPageTableFields()); // will include page_ id, ns, title
+ $this->addFields(array('cl_from', 'cl_sortkey'));
+ }
+
+ $this->addFieldsIf('cl_timestamp', $fld_timestamp);
+ $this->addTables(array('page','categorylinks')); // must be in this order for 'USE INDEX'
+ // Not needed after bug 10280 is applied to servers
+ if($params['sort'] == 'timestamp')
+ {
+ $this->addOption('USE INDEX', 'cl_timestamp');
+ $this->addOption('ORDER BY', 'cl_to, cl_timestamp' . ($params['dir'] == 'desc' ? ' DESC' : ''));
+ }
+ else
+ {
+ $this->addOption('USE INDEX', 'cl_sortkey');
+ $this->addOption('ORDER BY', 'cl_to, cl_sortkey' . ($params['dir'] == 'desc' ? ' DESC' : '') . ', cl_from');
+ }
+
+ $this->addWhere('cl_from=page_id');
+ $this->setContinuation($params['continue']);
+ $this->addWhereFld('cl_to', $categoryTitle->getDBkey());
+ $this->addWhereFld('page_namespace', $params['namespace']);
+
+ $limit = $params['limit'];
+ $this->addOption('LIMIT', $limit +1);
+
+ $db = $this->getDB();
+
+ $data = array ();
+ $count = 0;
+ $lastSortKey = null;
+ $res = $this->select(__METHOD__);
+ while ($row = $db->fetchObject($res)) {
+ if (++ $count > $limit) {
+ // We've reached the one extra which shows that there are additional pages to be had. Stop here...
+ // TODO: Security issue - if the user has no right to view next title, it will still be shown
+ $this->setContinueEnumParameter('continue', $this->getContinueStr($row, $lastSortKey));
+ break;
+ }
+
+ $lastSortKey = $row->cl_sortkey; // detect duplicate sortkeys
+
+ if (is_null($resultPageSet)) {
+ $vals = array();
+ if ($fld_ids)
+ $vals['pageid'] = intval($row->page_id);
+ if ($fld_title) {
+ $title = Title :: makeTitle($row->page_namespace, $row->page_title);
+ $vals['ns'] = intval($title->getNamespace());
+ $vals['title'] = $title->getPrefixedText();
+ }
+ if ($fld_sortkey)
+ $vals['sortkey'] = $row->cl_sortkey;
+ if ($fld_timestamp)
+ $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->cl_timestamp);
+ $data[] = $vals;
+ } else {
+ $resultPageSet->processDbRow($row);
+ }
+ }
+ $db->freeResult($res);
+
+ if (is_null($resultPageSet)) {
+ $this->getResult()->setIndexedTagName($data, 'cm');
+ $this->getResult()->addValue('query', $this->getModuleName(), $data);
+ }
+ }
+
+ private function getContinueStr($row, $lastSortKey) {
+ $ret = $row->cl_sortkey . '|';
+ if ($row->cl_sortkey == $lastSortKey) // duplicate sort key, add cl_from
+ $ret .= $row->cl_from;
+ return $ret;
+ }
+
+ /**
+ * Add DB WHERE clause to continue previous query based on 'continue' parameter
+ */
+ private function setContinuation($continue) {
+ if (is_null($continue))
+ return; // This is not a continuation request
+
+ $continueList = explode('|', $continue);
+ $hasError = count($continueList) != 2;
+ $from = 0;
+ if (!$hasError && strlen($continueList[1]) > 0) {
+ $from = intval($continueList[1]);
+ $hasError = ($from == 0);
+ }
+
+ if ($hasError)
+ $this->dieUsage("Invalid continue param. You should pass the original value returned by the previous query", "badcontinue");
+
+ $encSortKey = $this->getDB()->addQuotes($continueList[0]);
+ $encFrom = $this->getDB()->addQuotes($from);
+
+ if ($from != 0) {
+ // Duplicate sort key continue
+ $this->addWhere( "cl_sortkey>$encSortKey OR (cl_sortkey=$encSortKey AND cl_from>=$encFrom)" );
+ } else {
+ $this->addWhere( "cl_sortkey>=$encSortKey" );
+ }
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'category' => null,
+ 'prop' => array (
+ ApiBase :: PARAM_DFLT => 'ids|title',
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => array (
+ 'ids',
+ 'title',
+ 'sortkey',
+ 'timestamp',
+ )
+ ),
+ 'namespace' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => 'namespace',
+ ),
+ 'continue' => null,
+ 'limit' => array (
+ ApiBase :: PARAM_TYPE => 'limit',
+ ApiBase :: PARAM_DFLT => 10,
+ ApiBase :: PARAM_MIN => 1,
+ ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+ ),
+ 'sort' => array(
+ ApiBase :: PARAM_DFLT => 'sortkey',
+ ApiBase :: PARAM_TYPE => array(
+ 'sortkey',
+ 'timestamp'
+ )
+ ),
+ 'dir' => array(
+ ApiBase :: PARAM_DFLT => 'asc',
+ ApiBase :: PARAM_TYPE => array(
+ 'asc',
+ 'desc'
+ )
+ )
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'category' => 'Which category to enumerate (required)',
+ 'prop' => 'What pieces of information to include',
+ 'namespace' => 'Only include pages in these namespaces',
+ 'sort' => 'Property to sort by',
+ 'dir' => 'In which direction to sort',
+ 'continue' => 'For large categories, give the value retured from previous query',
+ 'limit' => 'The maximum number of pages to return.',
+ );
+ }
+
+ protected function getDescription() {
+ return 'List all pages in a given category';
+ }
+
+ protected function getExamples() {
+ return array (
+ "Get first 10 pages in the categories [[Physics]]:",
+ " api.php?action=query&list=categorymembers&cmcategory=Physics",
+ "Get page info about first 10 pages in the categories [[Physics]]:",
+ " api.php?action=query&generator=categorymembers&gcmcategory=Physics&prop=info",
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+
--- /dev/null
+<?php
+
+/*
+ * Created on Jul 2, 2007
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+/**
+ * Query module to enumerate all available pages.
+ *
+ * @addtogroup API
+ */
+class ApiQueryDeletedrevs extends ApiQueryBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'dr');
+ }
+
+ public function execute() {
+
+ global $wgUser;
+ // Before doing anything at all, let's check permissions
+ if(!$wgUser->isAllowed('deletedhistory'))
+ $this->dieUsage('You don\'t have permission to view deleted revision information', 'permissiondenied');
+
+ $db = $this->getDB();
+ $params = $this->extractRequestParams();
+ $prop = array_flip($params['prop']);
+ $fld_revid = isset($prop['revid']);
+ $fld_user = isset($prop['user']);
+ $fld_comment = isset($prop['comment']);
+ $fld_minor = isset($prop['minor']);
+ $fld_len = isset($prop['len']);
+ $fld_content = isset($prop['content']);
+ $fld_token = isset($prop['token']);
+
+ $result = $this->getResult();
+ $pageSet = $this->getPageSet();
+ $titles = $pageSet->getTitles();
+ $data = array();
+
+ $this->addTables('archive');
+ $this->addFields(array('ar_title', 'ar_namespace', 'ar_timestamp'));
+ if($fld_revid)
+ $this->addFields('ar_rev_id');
+ if($fld_user)
+ $this->addFields('ar_user_text');
+ if($fld_comment)
+ $this->addFields('ar_comment');
+ if($fld_minor)
+ $this->addFields('ar_minor_edit');
+ if($fld_len)
+ $this->addFields('ar_len');
+ if($fld_content)
+ {
+ $this->addTables('text');
+ $this->addFields(array('ar_text', 'ar_text_id', 'old_text', 'old_flags'));
+ $this->addWhere('ar_text_id = old_id');
+
+ // This also means stricter limits and stricter restrictions
+ if(!$wgUser->isAllowed('undelete'))
+ $this->dieUsage('You don\'t have permission to view deleted revision content', 'permissiondenied');
+ $userMax = ApiBase :: LIMIT_SML1;
+ $botMax = ApiBase :: LIMIT_SML2;
+ $this->validateLimit('limit', $params['limit'], 1, $userMax, $botMax);
+ }
+ if($fld_token)
+ // Undelete tokens are identical for all pages, so we cache one here
+ $token = $wgUser->editToken();
+
+ // We need a custom WHERE clause that matches all titles.
+ if(count($titles) > 0)
+ {
+ $lb = new LinkBatch($titles);
+ $where = $lb->constructSet('ar', $db);
+ $this->addWhere($where);
+ }
+
+ $this->addOption('LIMIT', $params['limit'] + 1);
+ $this->addWhereRange('ar_timestamp', $params['dir'], $params['start'], $params['end']);
+ if(isset($params['namespace']))
+ $this->addWhereFld('ar_namespace', $params['namespace']);
+ $res = $this->select(__METHOD__);
+ $pages = array();
+ $count = 0;
+ // First populate the $pages array
+ while($row = $db->fetchObject($res))
+ {
+ if($count++ == $params['limit'])
+ {
+ // We've had enough
+ $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->ar_timestamp));
+ break;
+ }
+
+ $rev = array();
+ $rev['timestamp'] = wfTimestamp(TS_ISO_8601, $row->ar_timestamp);
+ if($fld_revid)
+ $rev['revid'] = $row->ar_rev_id;
+ if($fld_user)
+ $rev['user'] = $row->ar_user_text;
+ if($fld_comment)
+ $rev['comment'] = $row->ar_comment;
+ if($fld_minor)
+ if($row->ar_minor_edit == 1)
+ $rev['minor'] = '';
+ if($fld_len)
+ $rev['len'] = $row->ar_len;
+ if($fld_content)
+ ApiResult::setContent($rev, Revision::getRevisionText($row));
+
+ $t = Title::makeTitle($row->ar_namespace, $row->ar_title);
+ if(!isset($pages[$t->getPrefixedText()]))
+ {
+ $pages[$t->getPrefixedText()] = array(
+ 'title' => $t->getPrefixedText(),
+ 'ns' => intval($row->ar_namespace),
+ 'revisions' => array($rev)
+ );
+ if($fld_token)
+ $pages[$t->getPrefixedText()]['token'] = $token;
+ }
+ else
+ $pages[$t->getPrefixedText()]['revisions'][] = $rev;
+ }
+ $db->freeResult($res);
+
+ // We don't want entire pagenames as keys, so let's make this array indexed
+ foreach($pages as $page)
+ {
+ $result->setIndexedTagName($page['revisions'], 'rev');
+ $data[] = $page;
+ }
+ $result->setIndexedTagName($data, 'page');
+ $result->addValue('query', $this->getModuleName(), $data);
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'start' => array(
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'end' => array(
+ ApiBase :: PARAM_TYPE => 'timestamp',
+ ),
+ 'dir' => array(
+ ApiBase :: PARAM_TYPE => array(
+ 'newer',
+ 'older'
+ ),
+ ApiBase :: PARAM_DFLT => 'older'
+ ),
+ 'namespace' => array(
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => 'namespace'
+ ),
+ 'limit' => array(
+ ApiBase :: PARAM_DFLT => 10,
+ ApiBase :: PARAM_TYPE => 'limit',
+ ApiBase :: PARAM_MIN => 1,
+ ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+ ),
+ 'prop' => array(
+ ApiBase :: PARAM_DFLT => 'user|comment',
+ ApiBase :: PARAM_TYPE => array(
+ 'revid',
+ 'user',
+ 'comment',
+ 'minor',
+ 'len',
+ 'content',
+ 'token'
+ ),
+ ApiBase :: PARAM_ISMULTI => true
+ )
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'start' => 'The timestamp to start enumerating from',
+ 'end' => 'The timestamp to stop enumerating at',
+ 'dir' => 'The direction in which to enumerate',
+ 'namespace' => 'The namespaces to search in',
+ 'limit' => 'The maximum amount of revisions to list',
+ 'prop' => 'Which properties to get'
+ );
+ }
+
+ protected function getDescription() {
+ return 'List deleted revisions.';
+ }
+
+ protected function getExamples() {
+ return array (
+ 'List the first 50 deleted revisions in the Category and Category talk namespaces',
+ ' api.php?action=query&list=deletedrevs&drdir=newer&drlimit=50&drnamespace=14|15',
+ 'List the last deleted revisions of Main Page and Talk:Main Page, with content:',
+ ' api.php?action=query&list=deletedrevs&titles=Main%20Page|Talk:Main%20Page&drprop=user|comment|content'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
--- /dev/null
+<?php
+
+/*
+ * Created on July 7, 2007
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+/**
+ * @addtogroup API
+ */
+class ApiQueryExtLinksUsage extends ApiQueryGeneratorBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'eu');
+ }
+
+ public function execute() {
+ $this->run();
+ }
+
+ public function executeGenerator($resultPageSet) {
+ $this->run($resultPageSet);
+ }
+
+ private function run($resultPageSet = null) {
+
+ $params = $this->extractRequestParams();
+
+ $protocol = $params['protocol'];
+ $query = $params['query'];
+ if (is_null($query))
+ $this->dieUsage('Missing required query parameter', 'params');
+
+ // Find the right prefix
+ global $wgUrlProtocols;
+ foreach ($wgUrlProtocols as $p) {
+ if( substr( $p, 0, strlen( $protocol ) ) === $protocol ) {
+ $protocol = $p;
+ break;
+ }
+ }
+
+ $likeQuery = LinkFilter::makeLike($query , $protocol);
+ if (!$likeQuery)
+ $this->dieUsage('Invalid query', 'bad_query');
+ $likeQuery = substr($likeQuery, 0, strpos($likeQuery,'%')+1);
+
+ $this->addTables(array('page','externallinks')); // must be in this order for 'USE INDEX'
+ $this->addOption('USE INDEX', 'el_index');
+
+ $db = $this->getDB();
+ $this->addWhere('page_id=el_from');
+ $this->addWhere('el_index LIKE ' . $db->addQuotes( $likeQuery ));
+ $this->addWhereFld('page_namespace', $params['namespace']);
+
+ $prop = array_flip($params['prop']);
+ $fld_ids = isset($prop['ids']);
+ $fld_title = isset($prop['title']);
+ $fld_url = isset($prop['url']);
+
+ if (is_null($resultPageSet)) {
+ $this->addFields(array (
+ 'page_id',
+ 'page_namespace',
+ 'page_title'
+ ));
+ $this->addFieldsIf('el_to', $fld_url);
+ } else {
+ $this->addFields($resultPageSet->getPageTableFields());
+ }
+
+ $limit = $params['limit'];
+ $offset = $params['offset'];
+ $this->addOption('LIMIT', $limit +1);
+ if (isset ($offset))
+ $this->addOption('OFFSET', $offset);
+
+ $res = $this->select(__METHOD__);
+
+ $data = array ();
+ $count = 0;
+ while ($row = $db->fetchObject($res)) {
+ if (++ $count > $limit) {
+ // We've reached the one extra which shows that there are additional pages to be had. Stop here...
+ $this->setContinueEnumParameter('offset', $offset+$limit+1);
+ break;
+ }
+
+ if (is_null($resultPageSet)) {
+ $vals = array();
+ if ($fld_ids)
+ $vals['pageid'] = intval($row->page_id);
+ if ($fld_title) {
+ $title = Title :: makeTitle($row->page_namespace, $row->page_title);
+ $vals['ns'] = intval($title->getNamespace());
+ $vals['title'] = $title->getPrefixedText();
+ }
+ if ($fld_url)
+ $vals['url'] = $row->el_to;
+ $data[] = $vals;
+ } else {
+ $resultPageSet->processDbRow($row);
+ }
+ }
+ $db->freeResult($res);
+
+ if (is_null($resultPageSet)) {
+ $result = $this->getResult();
+ $result->setIndexedTagName($data, $this->getModulePrefix());
+ $result->addValue('query', $this->getModuleName(), $data);
+ }
+ }
+
+ protected function getAllowedParams() {
+ global $wgUrlProtocols;
+ $protocols = array();
+ foreach ($wgUrlProtocols as $p) {
+ $protocols[] = substr($p, 0, strpos($p,':'));
+ }
+
+ return array (
+ 'prop' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_DFLT => 'ids|title|url',
+ ApiBase :: PARAM_TYPE => array (
+ 'ids',
+ 'title',
+ 'url'
+ )
+ ),
+ 'offset' => array (
+ ApiBase :: PARAM_TYPE => 'integer'
+ ),
+ 'protocol' => array (
+ ApiBase :: PARAM_TYPE => $protocols,
+ ApiBase :: PARAM_DFLT => 'http',
+ ),
+ 'query' => null,
+ 'namespace' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => 'namespace'
+ ),
+ 'limit' => array (
+ ApiBase :: PARAM_DFLT => 10,
+ ApiBase :: PARAM_TYPE => 'limit',
+ ApiBase :: PARAM_MIN => 1,
+ ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+ )
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'prop' => 'What pieces of information to include',
+ 'offset' => 'Used for paging. Use the value returned for "continue"',
+ 'protocol' => 'Protocol of the url',
+ 'query' => 'Search string without protocol. See [[Special:LinkSearch]]',
+ 'namespace' => 'The page namespace(s) to enumerate.',
+ 'limit' => 'How many entries to return.'
+ );
+ }
+
+ protected function getDescription() {
+ return 'Enumerate pages that contain a given URL';
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=query&list=exturlusage&euquery=www.mediawiki.org'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
--- /dev/null
+<?php
+
+/*
+ * Created on May 13, 2007
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ("ApiQueryBase.php");
+}
+
+/**
+ * A query module to list all external URLs found on a given set of pages.
+ *
+ * @addtogroup API
+ */
+class ApiQueryExternalLinks extends ApiQueryBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'el');
+ }
+
+ public function execute() {
+
+ $this->addFields(array (
+ 'el_from',
+ 'el_to'
+ ));
+
+ $this->addTables('externallinks');
+ $this->addWhereFld('el_from', array_keys($this->getPageSet()->getGoodTitles()));
+
+ $db = $this->getDB();
+ $res = $this->select(__METHOD__);
+
+ $data = array();
+ $lastId = 0; // database has no ID 0
+ while ($row = $db->fetchObject($res)) {
+ if ($lastId != $row->el_from) {
+ if($lastId != 0) {
+ $this->addPageSubItems($lastId, $data);
+ $data = array();
+ }
+ $lastId = $row->el_from;
+ }
+
+ $entry = array();
+ ApiResult :: setContent($entry, $row->el_to);
+ $data[] = $entry;
+ }
+
+ if($lastId != 0) {
+ $this->addPageSubItems($lastId, $data);
+ }
+
+ $db->freeResult($res);
+ }
+
+ protected function getDescription() {
+ return 'Returns all external urls (not interwikies) from the given page(s)';
+ }
+
+ protected function getExamples() {
+ return array (
+ "Get a list of external links on the [[Main Page]]:",
+ " api.php?action=query&prop=extlinks&titles=Main%20Page",
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+
--- /dev/null
+<?php
+
+/*
+ * Created on July 6, 2007
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+/**
+ * A query action to get image information and upload history.
+ *
+ * @addtogroup API
+ */
+class ApiQueryImageInfo extends ApiQueryBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'ii');
+ }
+
+ public function execute() {
+ $params = $this->extractRequestParams();
+
+ $history = $params['history'];
+
+ $prop = array_flip($params['prop']);
+ $fld_timestamp = isset($prop['timestamp']);
+ $fld_user = isset($prop['user']);
+ $fld_comment = isset($prop['comment']);
+ $fld_url = isset($prop['url']);
+ $fld_size = isset($prop['size']);
+ $fld_sha1 = isset($prop['sha1']);
+ $fld_metadata = isset($prop['metadata']);
+
+ $pageIds = $this->getPageSet()->getAllTitlesByNamespace();
+ if (!empty($pageIds[NS_IMAGE])) {
+ foreach ($pageIds[NS_IMAGE] as $dbKey => $pageId) {
+
+ $title = Title :: makeTitle(NS_IMAGE, $dbKey);
+ $img = wfFindFile($title);
+
+ $data = array();
+ if ( !$img ) {
+ $repository = '';
+ } else {
+
+ $repository = $img->getRepoName();
+
+ $isCur = true;
+ while($line = $img->nextHistoryLine()) { // assignment
+ $row = get_object_vars( $line );
+ $vals = array();
+ $prefix = $isCur ? 'img' : 'oi';
+
+ if ($fld_timestamp)
+ $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row["${prefix}_timestamp"]);
+ if ($fld_user) {
+ $vals['user'] = $row["${prefix}_user_text"];
+ if(!$row["${prefix}_user"])
+ $vals['anon'] = '';
+ }
+ if ($fld_size) {
+ $vals['size'] = intval($row["{$prefix}_size"]);
+ $vals['width'] = intval($row["{$prefix}_width"]);
+ $vals['height'] = intval($row["{$prefix}_height"]);
+ }
+ if ($fld_url)
+ $vals['url'] = $isCur ? $img->getURL() : $img->getArchiveUrl($row["oi_archive_name"]);
+ if ($fld_comment)
+ $vals['comment'] = $row["{$prefix}_description"];
+
+ if ($fld_sha1)
+ $vals['sha1'] = wfBaseConvert($row["{$prefix}_sha1"], 36, 16, 40);
+
+ if ($fld_metadata) {
+ $metadata = unserialize($row["{$prefix}_metadata"]);
+ $vals['metadata'] = $metadata ? $metadata : null;
+ $this->getResult()->setIndexedTagName_recursive($vals['metadata'], 'meta');
+ }
+
+ $data[] = $vals;
+
+ if (!$history) // Stop after the first line.
+ break;
+
+ $isCur = false;
+ }
+
+ $img->resetHistory();
+ }
+
+ $this->getResult()->addValue(array ('query', 'pages', intval($pageId)),
+ 'imagerepository',
+ $repository);
+ if (!empty($data))
+ $this->addPageSubItems($pageId, $data);
+ }
+ }
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'prop' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_DFLT => 'timestamp|user',
+ ApiBase :: PARAM_TYPE => array (
+ 'timestamp',
+ 'user',
+ 'comment',
+ 'url',
+ 'size',
+ 'sha1',
+ 'metadata'
+ )
+ ),
+ 'history' => false,
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'prop' => 'What image information to get.',
+ 'history' => 'Include upload history',
+ );
+ }
+
+ protected function getDescription() {
+ return array (
+ 'Returns image information and upload history'
+ );
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=query&titles=Image:Albert%20Einstein%20Head.jpg&prop=imageinfo',
+ 'api.php?action=query&titles=Image:Test.jpg&prop=imageinfo&iihistory&iiprop=timestamp|user|url',
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
--- /dev/null
+<?php
+
+/*
+ * Created on May 13, 2007
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ("ApiQueryBase.php");
+}
+
+/**
+ * This query adds <images> subelement to all pages with the list of images embedded into those pages.
+ *
+ * @addtogroup API
+ */
+class ApiQueryImages extends ApiQueryGeneratorBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'im');
+ }
+
+ public function execute() {
+ $this->run();
+ }
+
+ public function executeGenerator($resultPageSet) {
+ $this->run($resultPageSet);
+ }
+
+ private function run($resultPageSet = null) {
+
+ if ($this->getPageSet()->getGoodTitleCount() == 0)
+ return; // nothing to do
+
+ $this->addFields(array (
+ 'il_from',
+ 'il_to'
+ ));
+
+ $this->addTables('imagelinks');
+ $this->addWhereFld('il_from', array_keys($this->getPageSet()->getGoodTitles()));
+ $this->addOption('ORDER BY', "il_from, il_to");
+
+ $db = $this->getDB();
+ $res = $this->select(__METHOD__);
+
+ if (is_null($resultPageSet)) {
+
+ $data = array();
+ $lastId = 0; // database has no ID 0
+ while ($row = $db->fetchObject($res)) {
+ if ($lastId != $row->il_from) {
+ if($lastId != 0) {
+ $this->addPageSubItems($lastId, $data);
+ $data = array();
+ }
+ $lastId = $row->il_from;
+ }
+
+ $vals = array();
+ ApiQueryBase :: addTitleInfo($vals, Title :: makeTitle(NS_IMAGE, $row->il_to));
+ $data[] = $vals;
+ }
+
+ if($lastId != 0) {
+ $this->addPageSubItems($lastId, $data);
+ }
+
+ } else {
+
+ $titles = array();
+ while ($row = $db->fetchObject($res)) {
+ $titles[] = Title :: makeTitle(NS_IMAGE, $row->il_to);
+ }
+ $resultPageSet->populateFromTitles($titles);
+ }
+
+ $db->freeResult($res);
+ }
+
+ protected function getDescription() {
+ return 'Returns all images contained on the given page(s)';
+ }
+
+ protected function getExamples() {
+ return array (
+ "Get a list of images used in the [[Main Page]]:",
+ " api.php?action=query&prop=images&titles=Main%20Page",
+ "Get information about all images used in the [[Main Page]]:",
+ " api.php?action=query&generator=images&titles=Main%20Page&prop=info"
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+
--- /dev/null
+<?php
+
+/*
+ * Created on Sep 25, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+/**
+ * A query module to show basic page information.
+ *
+ * @addtogroup API
+ */
+class ApiQueryInfo extends ApiQueryBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'in');
+ }
+
+ public function requestExtraData($pageSet) {
+ $pageSet->requestField('page_restrictions');
+ $pageSet->requestField('page_is_redirect');
+ $pageSet->requestField('page_is_new');
+ $pageSet->requestField('page_counter');
+ $pageSet->requestField('page_touched');
+ $pageSet->requestField('page_latest');
+ $pageSet->requestField('page_len');
+ }
+
+ public function execute() {
+
+ global $wgUser;
+
+ $params = $this->extractRequestParams();
+ $fld_protection = false;
+ if(!is_null($params['prop'])) {
+ $prop = array_flip($params['prop']);
+ $fld_protection = isset($prop['protection']);
+ }
+ if(!is_null($params['token'])) {
+ $token = $params['token'];
+ $tok_edit = $this->getTokenFlag($token, 'edit');
+ $tok_delete = $this->getTokenFlag($token, 'delete');
+ $tok_protect = $this->getTokenFlag($token, 'protect');
+ $tok_move = $this->getTokenFlag($token, 'move');
+ }
+
+ $pageSet = $this->getPageSet();
+ $titles = $pageSet->getGoodTitles();
+ $result = $this->getResult();
+
+ $pageRestrictions = $pageSet->getCustomField('page_restrictions');
+ $pageIsRedir = $pageSet->getCustomField('page_is_redirect');
+ $pageIsNew = $pageSet->getCustomField('page_is_new');
+ $pageCounter = $pageSet->getCustomField('page_counter');
+ $pageTouched = $pageSet->getCustomField('page_touched');
+ $pageLatest = $pageSet->getCustomField('page_latest');
+ $pageLength = $pageSet->getCustomField('page_len');
+
+ if ($fld_protection && count($titles) > 0) {
+ $this->addTables('page_restrictions');
+ $this->addFields(array('pr_page', 'pr_type', 'pr_level', 'pr_expiry'));
+ $this->addWhereFld('pr_page', array_keys($titles));
+
+ $db = $this->getDB();
+ $res = $this->select(__METHOD__);
+ while($row = $db->fetchObject($res)) {
+ $protections[$row->pr_page][] = array(
+ 'type' => $row->pr_type,
+ 'level' => $row->pr_level,
+ 'expiry' => Block::decodeExpiry( $row->pr_expiry, TS_ISO_8601 )
+ );
+ }
+ $db->freeResult($res);
+ }
+
+ foreach ( $titles as $pageid => $title ) {
+ $pageInfo = array (
+ 'touched' => wfTimestamp(TS_ISO_8601, $pageTouched[$pageid]),
+ 'lastrevid' => intval($pageLatest[$pageid]),
+ 'counter' => intval($pageCounter[$pageid]),
+ 'length' => intval($pageLength[$pageid]),
+ );
+
+ if ($pageIsRedir[$pageid])
+ $pageInfo['redirect'] = '';
+
+ if ($pageIsNew[$pageid])
+ $pageInfo['new'] = '';
+
+ if (!is_null($token)) {
+ // Currently all tokens are generated the same way, but it might change
+ if ($tok_edit)
+ $pageInfo['edittoken'] = $wgUser->editToken();
+ if ($tok_delete)
+ $pageInfo['deletetoken'] = $wgUser->editToken();
+ if ($tok_protect)
+ $pageInfo['protecttoken'] = $wgUser->editToken();
+ if ($tok_move)
+ $pageInfo['movetoken'] = $wgUser->editToken();
+ }
+
+ if($fld_protection) {
+ if (isset($protections[$pageid])) {
+ $pageInfo['protection'] = $protections[$pageid];
+ $result->setIndexedTagName($pageInfo['protection'], 'pr');
+ } else {
+ # Also check old restrictions
+ if( $pageRestrictions[$pageid] ) {
+ foreach( explode( ':', trim( $pageRestrictions[$pageid] ) ) as $restrict ) {
+ $temp = explode( '=', trim( $restrict ) );
+ if(count($temp) == 1) {
+ // old old format should be treated as edit/move restriction
+ $restriction = trim( $temp[0] );
+ $pageInfo['protection'][] = array(
+ 'type' => 'edit',
+ 'level' => $restriction,
+ 'expiry' => 'infinity',
+ );
+ $pageInfo['protection'][] = array(
+ 'type' => 'move',
+ 'level' => $restriction,
+ 'expiry' => 'infinity',
+ );
+ } else {
+ $restriction = trim( $temp[1] );
+ $pageInfo['protection'][] = array(
+ 'type' => $temp[0],
+ 'level' => $restriction,
+ 'expiry' => 'infinity',
+ );
+ }
+ }
+ $result->setIndexedTagName($pageInfo['protection'], 'pr');
+ } else {
+ $pageInfo['protection'] = array();
+ }
+ }
+ }
+
+ $result->addValue(array (
+ 'query',
+ 'pages'
+ ), $pageid, $pageInfo);
+ }
+
+ // Get edit tokens for missing titles if requested
+ // Delete, protect and move tokens are N/A for missing titles anyway
+ if($tok_edit)
+ {
+ $missing = $pageSet->getMissingTitles();
+ $res = &$result->getData();
+ foreach($missing as $pageid => $title)
+ $res['query']['pages'][$pageid]['edittoken'] = $wgUser->editToken();
+ }
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'prop' => array (
+ ApiBase :: PARAM_DFLT => NULL,
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => array (
+ 'protection'
+ )),
+ 'token' => array (
+ ApiBase :: PARAM_DFLT => NULL,
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => array (
+ 'edit',
+ 'delete',
+ 'protect',
+ 'move',
+ )),
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'prop' => array (
+ 'Which additional properties to get:',
+ ' "protection" - List the protection level of each page'
+ ),
+ 'token' => 'Request a token to perform a data-modifying action on a page',
+ );
+ }
+
+
+ protected function getDescription() {
+ return 'Get basic page information such as namespace, title, last touched date, ...';
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=query&prop=info&titles=Main%20Page',
+ 'api.php?action=query&prop=info&inprop=protection&titles=Main%20Page'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+
--- /dev/null
+<?php
+
+/*
+ * Created on May 13, 2007
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ("ApiQueryBase.php");
+}
+
+/**
+ * A query module to list all langlinks (links to correspanding foreign language pages).
+ *
+ * @addtogroup API
+ */
+class ApiQueryLangLinks extends ApiQueryBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'll');
+ }
+
+ public function execute() {
+ $this->addFields(array (
+ 'll_from',
+ 'll_lang',
+ 'll_title'
+ ));
+
+ $this->addTables('langlinks');
+ $this->addWhereFld('ll_from', array_keys($this->getPageSet()->getGoodTitles()));
+ $this->addOption('ORDER BY', "ll_from, ll_lang");
+ $res = $this->select(__METHOD__);
+
+ $data = array();
+ $lastId = 0; // database has no ID 0
+ $db = $this->getDB();
+ while ($row = $db->fetchObject($res)) {
+
+ if ($lastId != $row->ll_from) {
+ if($lastId != 0) {
+ $this->addPageSubItems($lastId, $data);
+ $data = array();
+ }
+ $lastId = $row->ll_from;
+ }
+
+ $entry = array('lang'=>$row->ll_lang);
+ ApiResult :: setContent($entry, $row->ll_title);
+ $data[] = $entry;
+ }
+
+ if($lastId != 0) {
+ $this->addPageSubItems($lastId, $data);
+ }
+
+ $db->freeResult($res);
+ }
+
+ protected function getDescription() {
+ return 'Returns all interlanguage links from the given page(s)';
+ }
+
+ protected function getExamples() {
+ return array (
+ "Get interlanguage links from the [[Main Page]]:",
+ " api.php?action=query&prop=langlinks&titles=Main%20Page&redirects",
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+
--- /dev/null
+<?php
+
+/*
+ * Created on May 12, 2007
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ("ApiQueryBase.php");
+}
+
+/**
+ * A query module to list all wiki links on a given set of pages.
+ *
+ * @addtogroup API
+ */
+class ApiQueryLinks extends ApiQueryGeneratorBase {
+
+ const LINKS = 'links';
+ const TEMPLATES = 'templates';
+
+ private $table, $prefix, $description;
+
+ public function __construct($query, $moduleName) {
+
+ switch ($moduleName) {
+ case self::LINKS :
+ $this->table = 'pagelinks';
+ $this->prefix = 'pl';
+ $this->description = 'link';
+ break;
+ case self::TEMPLATES :
+ $this->table = 'templatelinks';
+ $this->prefix = 'tl';
+ $this->description = 'template';
+ break;
+ default :
+ ApiBase :: dieDebug(__METHOD__, 'Unknown module name');
+ }
+
+ parent :: __construct($query, $moduleName, $this->prefix);
+ }
+
+ public function execute() {
+ $this->run();
+ }
+
+ public function executeGenerator($resultPageSet) {
+ $this->run($resultPageSet);
+ }
+
+ private function run($resultPageSet = null) {
+
+ if ($this->getPageSet()->getGoodTitleCount() == 0)
+ return; // nothing to do
+
+ $params = $this->extractRequestParams();
+
+ $this->addFields(array (
+ $this->prefix . '_from pl_from',
+ $this->prefix . '_namespace pl_namespace',
+ $this->prefix . '_title pl_title'
+ ));
+
+ $this->addTables($this->table);
+ $this->addWhereFld($this->prefix . '_from', array_keys($this->getPageSet()->getGoodTitles()));
+ $this->addWhereFld($this->prefix . '_namespace', $params['namespace']);
+ $this->addOption('ORDER BY', str_replace('pl_', $this->prefix . '_', 'pl_from, pl_namespace, pl_title'));
+
+ $db = $this->getDB();
+ $res = $this->select(__METHOD__);
+
+ if (is_null($resultPageSet)) {
+
+ $data = array();
+ $lastId = 0; // database has no ID 0
+ while ($row = $db->fetchObject($res)) {
+ if ($lastId != $row->pl_from) {
+ if($lastId != 0) {
+ $this->addPageSubItems($lastId, $data);
+ $data = array();
+ }
+ $lastId = $row->pl_from;
+ }
+
+ $vals = array();
+ ApiQueryBase :: addTitleInfo($vals, Title :: makeTitle($row->pl_namespace, $row->pl_title));
+ $data[] = $vals;
+ }
+
+ if($lastId != 0) {
+ $this->addPageSubItems($lastId, $data);
+ }
+
+ } else {
+
+ $titles = array();
+ while ($row = $db->fetchObject($res)) {
+ $titles[] = Title :: makeTitle($row->pl_namespace, $row->pl_title);
+ }
+ $resultPageSet->populateFromTitles($titles);
+ }
+
+ $db->freeResult($res);
+ }
+
+ protected function getAllowedParams()
+ {
+ return array(
+ 'namespace' => array(
+ ApiBase :: PARAM_TYPE => 'namespace',
+ ApiBase :: PARAM_ISMULTI => true
+ )
+ );
+ }
+
+ protected function getParamDescription()
+ {
+ return array(
+ 'namespace' => "Show {$this->description}s in this namespace(s) only"
+ );
+ }
+
+ protected function getDescription() {
+ return "Returns all {$this->description}s from the given page(s)";
+ }
+
+ protected function getExamples() {
+ return array (
+ "Get {$this->description}s from the [[Main Page]]:",
+ " api.php?action=query&prop={$this->getModuleName()}&titles=Main%20Page",
+ "Get information about the {$this->description} pages in the [[Main Page]]:",
+ " api.php?action=query&generator={$this->getModuleName()}&titles=Main%20Page&prop=info",
+ "Get {$this->description}s from the Main Page in the User and Template namespaces:",
+ " api.php?action=query&prop={$this->getModuleName()}&titles=Main%20Page&{$this->prefix}namespace=2|10"
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+
--- /dev/null
+<?php
+
+/*
+ * Created on Oct 16, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+/**
+ * Query action to List the log events, with optional filtering by various parameters.
+ *
+ * @addtogroup API
+ */
+class ApiQueryLogEvents extends ApiQueryBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'le');
+ }
+
+ public function execute() {
+ $params = $this->extractRequestParams();
+ $db = $this->getDB();
+
+ $prop = $params['prop'];
+ $this->fld_ids = in_array('ids', $prop);
+ $this->fld_title = in_array('title', $prop);
+ $this->fld_type = in_array('type', $prop);
+ $this->fld_user = in_array('user', $prop);
+ $this->fld_timestamp = in_array('timestamp', $prop);
+ $this->fld_comment = in_array('comment', $prop);
+ $this->fld_details = in_array('details', $prop);
+
+ list($tbl_logging, $tbl_page, $tbl_user) = $db->tableNamesN('logging', 'page', 'user');
+
+ $this->addOption('STRAIGHT_JOIN');
+ $this->addTables("$tbl_logging LEFT OUTER JOIN $tbl_page ON " .
+ "log_namespace=page_namespace AND log_title=page_title " .
+ "INNER JOIN $tbl_user ON user_id=log_user");
+
+ $this->addFields(array (
+ 'log_type',
+ 'log_action',
+ 'log_timestamp',
+ ));
+
+ // FIXME: Fake out log_id for now until the column is live on Wikimedia
+ // $this->addFieldsIf('log_id', $this->fld_ids);
+ $this->addFieldsIf('page_id', $this->fld_ids);
+ $this->addFieldsIf('log_user', $this->fld_user);
+ $this->addFieldsIf('user_name', $this->fld_user);
+ $this->addFieldsIf('log_namespace', $this->fld_title);
+ $this->addFieldsIf('log_title', $this->fld_title);
+ $this->addFieldsIf('log_comment', $this->fld_comment);
+ $this->addFieldsIf('log_params', $this->fld_details);
+
+
+ $this->addWhereFld('log_deleted', 0);
+ $this->addWhereFld('log_type', $params['type']);
+ $this->addWhereRange('log_timestamp', $params['dir'], $params['start'], $params['end']);
+
+ $limit = $params['limit'];
+ $this->addOption('LIMIT', $limit +1);
+
+ $user = $params['user'];
+ if (!is_null($user)) {
+ $userid = $db->selectField('user', 'user_id', array (
+ 'user_name' => $user
+ ));
+ if (!$userid)
+ $this->dieUsage("User name $user not found", 'param_user');
+ $this->addWhereFld('log_user', $userid);
+ }
+
+ $title = $params['title'];
+ if (!is_null($title)) {
+ $titleObj = Title :: newFromText($title);
+ if (is_null($titleObj))
+ $this->dieUsage("Bad title value '$title'", 'param_title');
+ $this->addWhereFld('log_namespace', $titleObj->getNamespace());
+ $this->addWhereFld('log_title', $titleObj->getDBkey());
+ }
+
+ $data = array ();
+ $count = 0;
+ $res = $this->select(__METHOD__);
+ while ($row = $db->fetchObject($res)) {
+ if (++ $count > $limit) {
+ // We've reached the one extra which shows that there are additional pages to be had. Stop here...
+ $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->log_timestamp));
+ break;
+ }
+
+ $vals = $this->extractRowInfo($row);
+ if($vals)
+ $data[] = $vals;
+ }
+ $db->freeResult($res);
+
+ $this->getResult()->setIndexedTagName($data, 'item');
+ $this->getResult()->addValue('query', $this->getModuleName(), $data);
+ }
+
+ private function extractRowInfo($row) {
+ $vals = array();
+
+ if ($this->fld_ids) {
+ // FIXME: Fake out log_id for now until the column is live on Wikimedia
+ // $vals['logid'] = intval($row->log_id);
+ $vals['logid'] = 0;
+ $vals['pageid'] = intval($row->page_id);
+ }
+
+ if ($this->fld_title) {
+ $title = Title :: makeTitle($row->log_namespace, $row->log_title);
+ ApiQueryBase :: addTitleInfo($vals, $title);
+ }
+
+ if ($this->fld_type) {
+ $vals['type'] = $row->log_type;
+ $vals['action'] = $row->log_action;
+ }
+
+ if ($this->fld_details && $row->log_params !== '') {
+ $params = explode("\n", $row->log_params);
+ switch ($row->log_type) {
+ case 'move':
+ if (isset ($params[0])) {
+ $title = Title :: newFromText($params[0]);
+ if ($title) {
+ $vals2 = array();
+ ApiQueryBase :: addTitleInfo($vals2, $title, "new_");
+ $vals[$row->log_type] = $vals2;
+ $params = null;
+ }
+ }
+ break;
+ case 'patrol':
+ $vals2 = array();
+ list( $vals2['cur'], $vals2['prev'], $vals2['auto'] ) = $params;
+ $vals[$row->log_type] = $vals2;
+ $params = null;
+ break;
+ case 'rights':
+ $vals2 = array();
+ list( $vals2['old'], $vals2['new'] ) = $params;
+ $vals[$row->log_type] = $vals2;
+ $params = null;
+ break;
+ case 'block':
+ $vals2 = array();
+ list( $vals2['duration'], $vals2['flags'] ) = $params;
+ $vals[$row->log_type] = $vals2;
+ $params = null;
+ break;
+ }
+
+ if (isset($params)) {
+ $this->getResult()->setIndexedTagName($params, 'param');
+ $vals = array_merge($vals, $params);
+ }
+ }
+
+ if ($this->fld_user) {
+ $vals['user'] = $row->user_name;
+ if(!$row->log_user)
+ $vals['anon'] = '';
+ }
+ if ($this->fld_timestamp) {
+ $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->log_timestamp);
+ }
+ if ($this->fld_comment && !empty ($row->log_comment)) {
+ $vals['comment'] = $row->log_comment;
+ }
+
+ return $vals;
+ }
+
+
+ protected function getAllowedParams() {
+ global $wgLogTypes;
+ return array (
+ 'prop' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_DFLT => 'ids|title|type|user|timestamp|comment|details',
+ ApiBase :: PARAM_TYPE => array (
+ 'ids',
+ 'title',
+ 'type',
+ 'user',
+ 'timestamp',
+ 'comment',
+ 'details',
+ )
+ ),
+ 'type' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => $wgLogTypes
+ ),
+ 'start' => array (
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'end' => array (
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'dir' => array (
+ ApiBase :: PARAM_DFLT => 'older',
+ ApiBase :: PARAM_TYPE => array (
+ 'newer',
+ 'older'
+ )
+ ),
+ 'user' => null,
+ 'title' => null,
+ 'limit' => array (
+ ApiBase :: PARAM_DFLT => 10,
+ ApiBase :: PARAM_TYPE => 'limit',
+ ApiBase :: PARAM_MIN => 1,
+ ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+ )
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'type' => 'Filter log entries to only this type(s)',
+ 'start' => 'The timestamp to start enumerating from.',
+ 'end' => 'The timestamp to end enumerating.',
+ 'dir' => 'In which direction to enumerate.',
+ 'user' => 'Filter entries to those made by the given user.',
+ 'title' => 'Filter entries to those related to a page.',
+ 'limit' => 'How many total event entries to return.'
+ );
+ }
+
+ protected function getDescription() {
+ return 'Get events from logs.';
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=query&list=logevents'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+
--- /dev/null
+<?php
+
+/*
+ * Created on Oct 19, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+/**
+ * A query action to enumerate the recent changes that were done to the wiki.
+ * Various filters are supported.
+ *
+ * @addtogroup API
+ */
+class ApiQueryRecentChanges extends ApiQueryBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'rc');
+ }
+
+ private $fld_comment = false, $fld_user = false, $fld_flags = false,
+ $fld_timestamp = false, $fld_title = false, $fld_ids = false,
+ $fld_sizes = false;
+
+ /**
+ * Generates and outputs the result of this query based upon the provided parameters.
+ */
+ public function execute() {
+ /* Initialize vars */
+ $limit = $prop = $namespace = $show = $type = $dir = $start = $end = null;
+
+ /* Get the parameters of the request. */
+ extract($this->extractRequestParams());
+
+ /* Build our basic query. Namely, something along the lines of:
+ * SELECT * from recentchanges WHERE rc_timestamp > $start
+ * AND rc_timestamp < $end AND rc_namespace = $namespace
+ * AND rc_deleted = '0'
+ */
+ $this->addTables('recentchanges');
+ $this->addWhereRange('rc_timestamp', $dir, $start, $end);
+ $this->addWhereFld('rc_namespace', $namespace);
+ $this->addWhereFld('rc_deleted', 0);
+ if(!is_null($type))
+ $this->addWhereFld('rc_type', $this->parseRCType($type));
+
+ if (!is_null($show)) {
+ $show = array_flip($show);
+
+ /* Check for conflicting parameters. */
+ if ((isset ($show['minor']) && isset ($show['!minor']))
+ || (isset ($show['bot']) && isset ($show['!bot']))
+ || (isset ($show['anon']) && isset ($show['!anon']))) {
+
+ $this->dieUsage("Incorrect parameter - mutually exclusive values may not be supplied", 'show');
+ }
+
+ /* Add additional conditions to query depending upon parameters. */
+ $this->addWhereIf('rc_minor = 0', isset ($show['!minor']));
+ $this->addWhereIf('rc_minor != 0', isset ($show['minor']));
+ $this->addWhereIf('rc_bot = 0', isset ($show['!bot']));
+ $this->addWhereIf('rc_bot != 0', isset ($show['bot']));
+ $this->addWhereIf('rc_user = 0', isset ($show['anon']));
+ $this->addWhereIf('rc_user != 0', isset ($show['!anon']));
+ }
+
+ /* Add the fields we're concerned with to out query. */
+ $this->addFields(array (
+ 'rc_timestamp',
+ 'rc_namespace',
+ 'rc_title',
+ 'rc_type',
+ 'rc_moved_to_ns',
+ 'rc_moved_to_title'
+ ));
+
+ /* Determine what properties we need to display. */
+ if (!is_null($prop)) {
+ $prop = array_flip($prop);
+
+ /* Set up internal members based upon params. */
+ $this->fld_comment = isset ($prop['comment']);
+ $this->fld_user = isset ($prop['user']);
+ $this->fld_flags = isset ($prop['flags']);
+ $this->fld_timestamp = isset ($prop['timestamp']);
+ $this->fld_title = isset ($prop['title']);
+ $this->fld_ids = isset ($prop['ids']);
+ $this->fld_sizes = isset ($prop['sizes']);
+
+ /* Add fields to our query if they are specified as a needed parameter. */
+ $this->addFieldsIf('rc_id', $this->fld_ids);
+ $this->addFieldsIf('rc_cur_id', $this->fld_ids);
+ $this->addFieldsIf('rc_this_oldid', $this->fld_ids);
+ $this->addFieldsIf('rc_last_oldid', $this->fld_ids);
+ $this->addFieldsIf('rc_comment', $this->fld_comment);
+ $this->addFieldsIf('rc_user', $this->fld_user);
+ $this->addFieldsIf('rc_user_text', $this->fld_user);
+ $this->addFieldsIf('rc_minor', $this->fld_flags);
+ $this->addFieldsIf('rc_bot', $this->fld_flags);
+ $this->addFieldsIf('rc_new', $this->fld_flags);
+ $this->addFieldsIf('rc_old_len', $this->fld_sizes);
+ $this->addFieldsIf('rc_new_len', $this->fld_sizes);
+ }
+
+ /* Specify the limit for our query. It's $limit+1 because we (possibly) need to
+ * generate a "continue" parameter, to allow paging. */
+ $this->addOption('LIMIT', $limit +1);
+
+ /* Specify the index to use in the query as rc_timestamp, instead of rc_revid (default). */
+ $this->addOption('USE INDEX', 'rc_timestamp');
+
+ $data = array ();
+ $count = 0;
+
+ /* Perform the actual query. */
+ $db = $this->getDB();
+ $res = $this->select(__METHOD__);
+
+ /* Iterate through the rows, adding data extracted from them to our query result. */
+ while ($row = $db->fetchObject($res)) {
+ if (++ $count > $limit) {
+ // We've reached the one extra which shows that there are additional pages to be had. Stop here...
+ $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->rc_timestamp));
+ break;
+ }
+
+ /* Extract the data from a single row. */
+ $vals = $this->extractRowInfo($row);
+
+ /* Add that row's data to our final output. */
+ if($vals)
+ $data[] = $vals;
+ }
+
+ $db->freeResult($res);
+
+ /* Format the result */
+ $result = $this->getResult();
+ $result->setIndexedTagName($data, 'rc');
+ $result->addValue('query', $this->getModuleName(), $data);
+ }
+
+ /**
+ * Extracts from a single sql row the data needed to describe one recent change.
+ *
+ * @param $row The row from which to extract the data.
+ * @return An array mapping strings (descriptors) to their respective string values.
+ * @access private
+ */
+ private function extractRowInfo($row) {
+ /* If page was moved somewhere, get the title of the move target. */
+ $movedToTitle = false;
+ if (!empty($row->rc_moved_to_title))
+ $movedToTitle = Title :: makeTitle($row->rc_moved_to_ns, $row->rc_moved_to_title);
+
+ /* Determine the title of the page that has been changed. */
+ $title = Title :: makeTitle($row->rc_namespace, $row->rc_title);
+
+ /* Our output data. */
+ $vals = array ();
+
+ $type = intval ( $row->rc_type );
+
+ /* Determine what kind of change this was. */
+ switch ( $type ) {
+ case RC_EDIT: $vals['type'] = 'edit'; break;
+ case RC_NEW: $vals['type'] = 'new'; break;
+ case RC_MOVE: $vals['type'] = 'move'; break;
+ case RC_LOG: $vals['type'] = 'log'; break;
+ case RC_MOVE_OVER_REDIRECT: $vals['type'] = 'move over redirect'; break;
+ default: $vals['type'] = $type;
+ }
+
+ /* Create a new entry in the result for the title. */
+ if ($this->fld_title) {
+ ApiQueryBase :: addTitleInfo($vals, $title);
+ if ($movedToTitle)
+ ApiQueryBase :: addTitleInfo($vals, $movedToTitle, "new_");
+ }
+
+ /* Add ids, such as rcid, pageid, revid, and oldid to the change's info. */
+ if ($this->fld_ids) {
+ $vals['rcid'] = intval($row->rc_id);
+ $vals['pageid'] = intval($row->rc_cur_id);
+ $vals['revid'] = intval($row->rc_this_oldid);
+ $vals['old_revid'] = intval( $row->rc_last_oldid );
+ }
+
+ /* Add user data and 'anon' flag, if use is anonymous. */
+ if ($this->fld_user) {
+ $vals['user'] = $row->rc_user_text;
+ if(!$row->rc_user)
+ $vals['anon'] = '';
+ }
+
+ /* Add flags, such as new, minor, bot. */
+ if ($this->fld_flags) {
+ if ($row->rc_bot)
+ $vals['bot'] = '';
+ if ($row->rc_new)
+ $vals['new'] = '';
+ if ($row->rc_minor)
+ $vals['minor'] = '';
+ }
+
+ /* Add sizes of each revision. (Only available on 1.10+) */
+ if ($this->fld_sizes) {
+ $vals['oldlen'] = intval($row->rc_old_len);
+ $vals['newlen'] = intval($row->rc_new_len);
+ }
+
+ /* Add the timestamp. */
+ if ($this->fld_timestamp)
+ $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->rc_timestamp);
+
+ /* Add edit summary / log summary. */
+ if ($this->fld_comment && !empty ($row->rc_comment)) {
+ $vals['comment'] = $row->rc_comment;
+ }
+
+ return $vals;
+ }
+
+ private function parseRCType($type)
+ {
+ if(is_array($type))
+ {
+ $retval = array();
+ foreach($type as $t)
+ $retval[] = $this->parseRCType($t);
+ return $retval;
+ }
+ switch($type)
+ {
+ case 'edit': return RC_EDIT;
+ case 'new': return RC_NEW;
+ case 'log': return RC_LOG;
+ }
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'start' => array (
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'end' => array (
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'dir' => array (
+ ApiBase :: PARAM_DFLT => 'older',
+ ApiBase :: PARAM_TYPE => array (
+ 'newer',
+ 'older'
+ )
+ ),
+ 'namespace' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => 'namespace'
+ ),
+ 'prop' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_DFLT => 'title|timestamp|ids',
+ ApiBase :: PARAM_TYPE => array (
+ 'user',
+ 'comment',
+ 'flags',
+ 'timestamp',
+ 'title',
+ 'ids',
+ 'sizes'
+ )
+ ),
+ 'show' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => array (
+ 'minor',
+ '!minor',
+ 'bot',
+ '!bot',
+ 'anon',
+ '!anon'
+ )
+ ),
+ 'limit' => array (
+ ApiBase :: PARAM_DFLT => 10,
+ ApiBase :: PARAM_TYPE => 'limit',
+ ApiBase :: PARAM_MIN => 1,
+ ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+ ),
+ 'type' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => array (
+ 'edit',
+ 'new',
+ 'log'
+ )
+ )
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'start' => 'The timestamp to start enumerating from.',
+ 'end' => 'The timestamp to end enumerating.',
+ 'dir' => 'In which direction to enumerate.',
+ 'namespace' => 'Filter log entries to only this namespace(s)',
+ 'prop' => 'Include additional pieces of information',
+ 'show' => array (
+ 'Show only items that meet this criteria.',
+ 'For example, to see only minor edits done by logged-in users, set show=minor|!anon'
+ ),
+ 'type' => 'Which types of changes to show.',
+ 'limit' => 'How many total pages to return.'
+ );
+ }
+
+ protected function getDescription() {
+ return 'Enumerate recent changes';
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=query&list=recentchanges'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+
--- /dev/null
+<?php
+
+/*
+ * Created on Sep 7, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+/**
+ * A query action to enumerate revisions of a given page, or show top revisions of multiple pages.
+ * Various pieces of information may be shown - flags, comments, and the actual wiki markup of the rev.
+ * In the enumeration mode, ranges of revisions may be requested and filtered.
+ *
+ * @addtogroup API
+ */
+class ApiQueryRevisions extends ApiQueryBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'rv');
+ }
+
+ private $fld_ids = false, $fld_flags = false, $fld_timestamp = false, $fld_size = false,
+ $fld_comment = false, $fld_user = false, $fld_content = false;
+
+ public function execute() {
+ $limit = $startid = $endid = $start = $end = $dir = $prop = $user = $excludeuser = $token = null;
+ extract($this->extractRequestParams());
+
+ // If any of those parameters are used, work in 'enumeration' mode.
+ // Enum mode can only be used when exactly one page is provided.
+ // Enumerating revisions on multiple pages make it extremely
+ // difficult to manage continuations and require additional SQL indexes
+ $enumRevMode = (!is_null($user) || !is_null($excludeuser) || !is_null($limit) || !is_null($startid) || !is_null($endid) || $dir === 'newer' || !is_null($start) || !is_null($end));
+
+
+ $pageSet = $this->getPageSet();
+ $pageCount = $pageSet->getGoodTitleCount();
+ $revCount = $pageSet->getRevisionCount();
+
+ // Optimization -- nothing to do
+ if ($revCount === 0 && $pageCount === 0)
+ return;
+
+ if ($revCount > 0 && $enumRevMode)
+ $this->dieUsage('The revids= parameter may not be used with the list options (limit, startid, endid, dirNewer, start, end).', 'revids');
+
+ if ($pageCount > 1 && $enumRevMode)
+ $this->dieUsage('titles, pageids or a generator was used to supply multiple pages, but the limit, startid, endid, dirNewer, user, excludeuser, start and end parameters may only be used on a single page.', 'multpages');
+
+ $this->addTables('revision');
+ $this->addWhere('rev_deleted=0');
+
+ $prop = array_flip($prop);
+
+ // These field are needed regardless of the client requesting them
+ $this->addFields('rev_id');
+ $this->addFields('rev_page');
+
+ // Optional fields
+ $this->fld_ids = isset ($prop['ids']);
+ // $this->addFieldsIf('rev_text_id', $this->fld_ids); // should this be exposed?
+ $this->fld_flags = $this->addFieldsIf('rev_minor_edit', isset ($prop['flags']));
+ $this->fld_timestamp = $this->addFieldsIf('rev_timestamp', isset ($prop['timestamp']));
+ $this->fld_comment = $this->addFieldsIf('rev_comment', isset ($prop['comment']));
+ $this->fld_size = $this->addFieldsIf('rev_len', isset ($prop['size']));
+ if(!is_null($token))
+ {
+ $this->tok_rollback = $this->getTokenFlag($token, 'rollback');
+ }
+
+ if (isset ($prop['user'])) {
+ $this->addFields('rev_user');
+ $this->addFields('rev_user_text');
+ $this->fld_user = true;
+ }
+ else if($this->tok_rollback)
+ $this->addFields('rev_user_text');
+
+ if (isset ($prop['content'])) {
+
+ // For each page we will request, the user must have read rights for that page
+ foreach ($pageSet->getGoodTitles() as $title) {
+ if( !$title->userCanRead() )
+ $this->dieUsage(
+ 'The current user is not allowed to read ' . $title->getPrefixedText(),
+ 'accessdenied');
+ }
+
+ $this->addTables('text');
+ $this->addWhere('rev_text_id=old_id');
+ $this->addFields('old_id');
+ $this->addFields('old_text');
+ $this->addFields('old_flags');
+
+ $this->fld_content = true;
+
+ $this->expandTemplates = $expandtemplates;
+ }
+
+ $userMax = ( $this->fld_content ? ApiBase::LIMIT_SML1 : ApiBase::LIMIT_BIG1 );
+ $botMax = ( $this->fld_content ? ApiBase::LIMIT_SML2 : ApiBase::LIMIT_BIG2 );
+
+ if ($enumRevMode) {
+
+ // This is mostly to prevent parameter errors (and optimize SQL?)
+ if (!is_null($startid) && !is_null($start))
+ $this->dieUsage('start and startid cannot be used together', 'badparams');
+
+ if (!is_null($endid) && !is_null($end))
+ $this->dieUsage('end and endid cannot be used together', 'badparams');
+
+ if(!is_null($user) && !is_null( $excludeuser))
+ $this->dieUsage('user and excludeuser cannot be used together', 'badparams');
+
+ // This code makes an assumption that sorting by rev_id and rev_timestamp produces
+ // the same result. This way users may request revisions starting at a given time,
+ // but to page through results use the rev_id returned after each page.
+ // Switching to rev_id removes the potential problem of having more than
+ // one row with the same timestamp for the same page.
+ // The order needs to be the same as start parameter to avoid SQL filesort.
+
+ if (is_null($startid) && is_null($endid))
+ $this->addWhereRange('rev_timestamp', $dir, $start, $end);
+ else
+ $this->addWhereRange('rev_id', $dir, $startid, $endid);
+
+ // must manually initialize unset limit
+ if (is_null($limit))
+ $limit = 10;
+ $this->validateLimit('limit', $limit, 1, $userMax, $botMax);
+
+ // There is only one ID, use it
+ $this->addWhereFld('rev_page', current(array_keys($pageSet->getGoodTitles())));
+
+ if(!is_null($user)) {
+ $this->addWhereFld('rev_user_text', $user);
+ } elseif (!is_null( $excludeuser)) {
+ $this->addWhere('rev_user_text != ' . $this->getDB()->addQuotes($excludeuser));
+ }
+ }
+ elseif ($revCount > 0) {
+ $this->validateLimit('rev_count', $revCount, 1, $userMax, $botMax);
+
+ // Get all revision IDs
+ $this->addWhereFld('rev_id', array_keys($pageSet->getRevisionIDs()));
+
+ // assumption testing -- we should never get more then $revCount rows.
+ $limit = $revCount;
+ }
+ elseif ($pageCount > 0) {
+ // When working in multi-page non-enumeration mode,
+ // limit to the latest revision only
+ $this->addTables('page');
+ $this->addWhere('page_id=rev_page');
+ $this->addWhere('page_latest=rev_id');
+ $this->validateLimit('page_count', $pageCount, 1, $userMax, $botMax);
+
+ // Get all page IDs
+ $this->addWhereFld('page_id', array_keys($pageSet->getGoodTitles()));
+
+ // assumption testing -- we should never get more then $pageCount rows.
+ $limit = $pageCount;
+ } else
+ ApiBase :: dieDebug(__METHOD__, 'param validation?');
+
+ $this->addOption('LIMIT', $limit +1);
+
+ $data = array ();
+ $count = 0;
+ $res = $this->select(__METHOD__);
+
+ $db = $this->getDB();
+ while ($row = $db->fetchObject($res)) {
+
+ if (++ $count > $limit) {
+ // We've reached the one extra which shows that there are additional pages to be had. Stop here...
+ if (!$enumRevMode)
+ ApiBase :: dieDebug(__METHOD__, 'Got more rows then expected'); // bug report
+ $this->setContinueEnumParameter('startid', intval($row->rev_id));
+ break;
+ }
+
+ $this->getResult()->addValue(
+ array (
+ 'query',
+ 'pages',
+ intval($row->rev_page),
+ 'revisions'),
+ null,
+ $this->extractRowInfo($row));
+ }
+ $db->freeResult($res);
+
+ // Ensure that all revisions are shown as '<rev>' elements
+ $result = $this->getResult();
+ if ($result->getIsRawMode()) {
+ $data =& $result->getData();
+ foreach ($data['query']['pages'] as & $page) {
+ if (is_array($page) && array_key_exists('revisions', $page)) {
+ $result->setIndexedTagName($page['revisions'], 'rev');
+ }
+ }
+ }
+ }
+
+ private function extractRowInfo($row) {
+
+ $vals = array ();
+
+ if ($this->fld_ids) {
+ $vals['revid'] = intval($row->rev_id);
+ // $vals['oldid'] = intval($row->rev_text_id); // todo: should this be exposed?
+ }
+
+ if ($this->fld_flags && $row->rev_minor_edit)
+ $vals['minor'] = '';
+
+ if ($this->fld_user) {
+ $vals['user'] = $row->rev_user_text;
+ if (!$row->rev_user)
+ $vals['anon'] = '';
+ }
+
+ if ($this->fld_timestamp) {
+ $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->rev_timestamp);
+ }
+
+ if ($this->fld_size && !is_null($row->rev_len)) {
+ $vals['size'] = intval($row->rev_len);
+ }
+
+ if ($this->fld_comment && !empty ($row->rev_comment)) {
+ $vals['comment'] = $row->rev_comment;
+ }
+
+ if($this->tok_rollback || ($this->fld_content && $this->expandTemplates))
+ $title = Title::newFromID($row->rev_page);
+
+ if($this->tok_rollback) {
+ global $wgUser;
+ $vals['rollbacktoken'] = $wgUser->editToken(array($title->getPrefixedText(), $row->rev_user_text));
+ }
+
+
+ if ($this->fld_content) {
+ $text = Revision :: getRevisionText($row);
+ if ($this->expandTemplates) {
+ global $wgParser;
+ $text = $wgParser->preprocess( $text, $title, new ParserOptions() );
+ }
+ ApiResult :: setContent($vals, $text);
+ }
+ return $vals;
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'prop' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_DFLT => 'ids|timestamp|flags|comment|user',
+ ApiBase :: PARAM_TYPE => array (
+ 'ids',
+ 'flags',
+ 'timestamp',
+ 'user',
+ 'size',
+ 'comment',
+ 'content',
+ )
+ ),
+ 'limit' => array (
+ ApiBase :: PARAM_TYPE => 'limit',
+ ApiBase :: PARAM_MIN => 1,
+ ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+ ),
+ 'startid' => array (
+ ApiBase :: PARAM_TYPE => 'integer'
+ ),
+ 'endid' => array (
+ ApiBase :: PARAM_TYPE => 'integer'
+ ),
+ 'start' => array (
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'end' => array (
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'dir' => array (
+ ApiBase :: PARAM_DFLT => 'older',
+ ApiBase :: PARAM_TYPE => array (
+ 'newer',
+ 'older'
+ )
+ ),
+ 'user' => array(
+ ApiBase :: PARAM_TYPE => 'user'
+ ),
+ 'excludeuser' => array(
+ ApiBase :: PARAM_TYPE => 'user'
+ ),
+
+ 'expandtemplates' => false,
+ 'token' => array(
+ ApiBase :: PARAM_TYPE => array(
+ 'rollback'
+ ),
+ ApiBase :: PARAM_ISMULTI => true
+ ),
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'prop' => 'Which properties to get for each revision.',
+ 'limit' => 'limit how many revisions will be returned (enum)',
+ 'startid' => 'from which revision id to start enumeration (enum)',
+ 'endid' => 'stop revision enumeration on this revid (enum)',
+ 'start' => 'from which revision timestamp to start enumeration (enum)',
+ 'end' => 'enumerate up to this timestamp (enum)',
+ 'dir' => 'direction of enumeration - towards "newer" or "older" revisions (enum)',
+ 'user' => 'only include revisions made by user',
+ 'excludeuser' => 'exclude revisions made by user',
+ 'expandtemplates' => 'expand templates in revision content',
+ 'token' => 'Which tokens to obtain for each revision',
+ );
+ }
+
+ protected function getDescription() {
+ return array (
+ 'Get revision information.',
+ 'This module may be used in several ways:',
+ ' 1) Get data about a set of pages (last revision), by setting titles or pageids parameter.',
+ ' 2) Get revisions for one given page, by using titles/pageids with start/end/limit params.',
+ ' 3) Get data about a set of revisions by setting their IDs with revids parameter.',
+ 'All parameters marked as (enum) may only be used with a single page (#2).'
+ );
+ }
+
+ protected function getExamples() {
+ return array (
+ 'Get data with content for the last revision of titles "API" and "Main Page":',
+ ' api.php?action=query&prop=revisions&titles=API|Main%20Page&rvprop=timestamp|user|comment|content',
+ 'Get last 5 revisions of the "Main Page":',
+ ' api.php?action=query&prop=revisions&titles=Main%20Page&rvlimit=5&rvprop=timestamp|user|comment',
+ 'Get first 5 revisions of the "Main Page":',
+ ' api.php?action=query&prop=revisions&titles=Main%20Page&rvlimit=5&rvprop=timestamp|user|comment&rvdir=newer',
+ 'Get first 5 revisions of the "Main Page" made after 2006-05-01:',
+ ' api.php?action=query&prop=revisions&titles=Main%20Page&rvlimit=5&rvprop=timestamp|user|comment&rvdir=newer&rvstart=20060501000000',
+ 'Get first 5 revisions of the "Main Page" that were not made made by anonymous user "127.0.0.1"',
+ ' api.php?action=query&prop=revisions&titles=Main%20Page&rvlimit=5&rvprop=timestamp|user|comment&rvexcludeuser=127.0.0.1',
+ 'Get first 5 revisions of the "Main Page" that were made by the user "MediaWiki default"',
+ ' api.php?action=query&prop=revisions&titles=Main%20Page&rvlimit=5&rvprop=timestamp|user|comment&rvuser=MediaWiki%20default',
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+
--- /dev/null
+<?php
+
+/*
+ * Created on July 30, 2007
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2007 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+/**
+ * Query module to perform full text search within wiki titles and content
+ *
+ * @addtogroup API
+ */
+class ApiQuerySearch extends ApiQueryGeneratorBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'sr');
+ }
+
+ public function execute() {
+ $this->run();
+ }
+
+ public function executeGenerator($resultPageSet) {
+ $this->run($resultPageSet);
+ }
+
+ private function run($resultPageSet = null) {
+
+ $params = $this->extractRequestParams();
+
+ $limit = $params['limit'];
+ $query = $params['search'];
+ if (is_null($query) || empty($query))
+ $this->dieUsage("empty search string is not allowed", 'param-search');
+
+ $search = SearchEngine::create();
+ $search->setLimitOffset( $limit+1, $params['offset'] );
+ $search->setNamespaces( $params['namespace'] );
+ $search->showRedirects = $params['redirects'];
+
+ if ($params['what'] == 'text')
+ $matches = $search->searchText( $query );
+ else
+ $matches = $search->searchTitle( $query );
+
+ $data = array ();
+ $count = 0;
+ while( $result = $matches->next() ) {
+ if (++ $count > $limit) {
+ // We've reached the one extra which shows that there are additional items to be had. Stop here...
+ $this->setContinueEnumParameter('offset', $params['offset'] + $params['limit']);
+ break;
+ }
+
+ $title = $result->getTitle();
+ if (is_null($resultPageSet)) {
+ $data[] = array(
+ 'ns' => intval($title->getNamespace()),
+ 'title' => $title->getPrefixedText());
+ } else {
+ $data[] = $title;
+ }
+ }
+
+ if (is_null($resultPageSet)) {
+ $result = $this->getResult();
+ $result->setIndexedTagName($data, 'p');
+ $result->addValue('query', $this->getModuleName(), $data);
+ } else {
+ $resultPageSet->populateFromTitles($data);
+ }
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'search' => null,
+ 'namespace' => array (
+ ApiBase :: PARAM_DFLT => 0,
+ ApiBase :: PARAM_TYPE => 'namespace',
+ ApiBase :: PARAM_ISMULTI => true,
+ ),
+ 'what' => array (
+ ApiBase :: PARAM_DFLT => 'title',
+ ApiBase :: PARAM_TYPE => array (
+ 'title',
+ 'text',
+ )
+ ),
+ 'redirects' => false,
+ 'offset' => 0,
+ 'limit' => array (
+ ApiBase :: PARAM_DFLT => 10,
+ ApiBase :: PARAM_TYPE => 'limit',
+ ApiBase :: PARAM_MIN => 1,
+ ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+ )
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'search' => 'Search for all page titles (or content) that has this value.',
+ 'namespace' => 'The namespace(s) to enumerate.',
+ 'what' => 'Search inside the text or titles.',
+ 'redirects' => 'Include redirect pages in the search.',
+ 'offset' => 'Use this value to continue paging (return by query)',
+ 'limit' => 'How many total pages to return.'
+ );
+ }
+
+ protected function getDescription() {
+ return 'Perform a full text search';
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=query&list=search&srsearch=meaning',
+ 'api.php?action=query&list=search&srwhat=text&srsearch=meaning',
+ 'api.php?action=query&generator=search&gsrsearch=meaning&prop=info',
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+
--- /dev/null
+<?php
+
+/*
+ * Created on Sep 25, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+/**
+ * A query action to return meta information about the wiki site.
+ *
+ * @addtogroup API
+ */
+class ApiQuerySiteinfo extends ApiQueryBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'si');
+ }
+
+ public function execute() {
+
+ $params = $this->extractRequestParams();
+
+ foreach ($params['prop'] as $p) {
+ switch ($p) {
+ default :
+ ApiBase :: dieDebug(__METHOD__, "Unknown prop=$p");
+ case 'general' :
+ $this->appendGeneralInfo($p);
+ break;
+ case 'namespaces' :
+ $this->appendNamespaces($p);
+ break;
+ case 'interwikimap' :
+ $filteriw = isset($params['filteriw']) ? $params['filteriw'] : false;
+ $this->appendInterwikiMap($p, $filteriw);
+ break;
+ case 'dbrepllag' :
+ $this->appendDbReplLagInfo($p, $params['showalldb']);
+ break;
+ case 'statistics' :
+ $this->appendStatistics($p);
+ break;
+ }
+ }
+ }
+
+ protected function appendGeneralInfo($property) {
+ global $wgSitename, $wgVersion, $wgCapitalLinks, $wgRightsCode, $wgRightsText, $wgLanguageCode, $IP;
+
+ $data = array ();
+ $mainPage = Title :: newFromText(wfMsgForContent('mainpage'));
+ $data['mainpage'] = $mainPage->getText();
+ $data['base'] = $mainPage->getFullUrl();
+ $data['sitename'] = $wgSitename;
+ $data['generator'] = "MediaWiki $wgVersion";
+
+ $svn = SpecialVersion::getSvnRevision ( $IP );
+ if ( $svn ) $data['rev'] = $svn;
+
+ $data['case'] = $wgCapitalLinks ? 'first-letter' : 'case-sensitive'; // 'case-insensitive' option is reserved for future
+ if (isset($wgRightsCode))
+ $data['rightscode'] = $wgRightsCode;
+ $data['rights'] = $wgRightsText;
+ $data['lang'] = $wgLanguageCode;
+
+ $this->getResult()->addValue('query', $property, $data);
+ }
+
+ protected function appendNamespaces($property) {
+ global $wgContLang;
+
+ $data = array ();
+ foreach ($wgContLang->getFormattedNamespaces() as $ns => $title) {
+ $data[$ns] = array (
+ 'id' => $ns
+ );
+ ApiResult :: setContent($data[$ns], $title);
+ }
+
+ $this->getResult()->setIndexedTagName($data, 'ns');
+ $this->getResult()->addValue('query', $property, $data);
+ }
+
+ protected function appendInterwikiMap($property, $filter) {
+
+ $this->resetQueryParams();
+ $this->addTables('interwiki');
+ $this->addFields(array('iw_prefix', 'iw_local', 'iw_url'));
+
+ if($filter === 'local') {
+ $this->addWhere('iw_local = 1');
+ } elseif($filter === '!local') {
+ $this->addWhere('iw_local = 0');
+ } elseif($filter !== false) {
+ ApiBase :: dieDebug(__METHOD__, "Unknown filter=$filter");
+ }
+
+ $this->addOption('ORDER BY', 'iw_prefix');
+
+ $db = $this->getDB();
+ $res = $this->select(__METHOD__);
+
+ $data = array();
+ while($row = $db->fetchObject($res))
+ {
+ $val['prefix'] = $row->iw_prefix;
+ if ($row->iw_local == '1')
+ $val['local'] = '';
+// $val['trans'] = intval($row->iw_trans); // should this be exposed?
+ $val['url'] = $row->iw_url;
+
+ $data[] = $val;
+ }
+ $db->freeResult($res);
+
+ $this->getResult()->setIndexedTagName($data, 'iw');
+ $this->getResult()->addValue('query', $property, $data);
+ }
+
+ protected function appendDbReplLagInfo($property, $includeAll) {
+ global $wgLoadBalancer, $wgShowHostnames;
+
+ $data = array();
+
+ if ($includeAll) {
+ if (!$wgShowHostnames)
+ $this->dieUsage('Cannot view all servers info unless $wgShowHostnames is true', 'includeAllDenied');
+
+ global $wgDBservers;
+ $lags = $wgLoadBalancer->getLagTimes();
+ foreach( $lags as $i => $lag ) {
+ $data[] = array (
+ 'host' => $wgDBservers[$i]['host'],
+ 'lag' => $lag);
+ }
+ } else {
+ list( $host, $lag ) = $wgLoadBalancer->getMaxLag();
+ $data[] = array (
+ 'host' => $wgShowHostnames ? $host : '',
+ 'lag' => $lag);
+ }
+
+ $result = $this->getResult();
+ $result->setIndexedTagName($data, 'db');
+ $result->addValue('query', $property, $data);
+ }
+
+ protected function appendStatistics($property) {
+ $data = array ();
+ $data['pages'] = intval(SiteStats::pages());
+ $data['articles'] = intval(SiteStats::articles());
+ $data['views'] = intval(SiteStats::views());
+ $data['edits'] = intval(SiteStats::edits());
+ $data['images'] = intval(SiteStats::images());
+ $data['users'] = intval(SiteStats::users());
+ $data['admins'] = intval(SiteStats::admins());
+ $data['jobs'] = intval(SiteStats::jobs());
+ $this->getResult()->addValue('query', $property, $data);
+ }
+
+ protected function getAllowedParams() {
+ return array (
+
+ 'prop' => array (
+ ApiBase :: PARAM_DFLT => 'general',
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => array (
+ 'general',
+ 'namespaces',
+ 'interwikimap',
+ 'dbrepllag',
+ 'statistics',
+ )),
+
+ 'filteriw' => array (
+ ApiBase :: PARAM_TYPE => array (
+ 'local',
+ '!local',
+ )),
+
+ 'showalldb' => false,
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'prop' => array (
+ 'Which sysinfo properties to get:',
+ ' "general" - Overall system information',
+ ' "namespaces" - List of registered namespaces (localized)',
+ ' "statistics" - Returns site statistics',
+ ' "interwikimap" - Returns interwiki map (optionally filtered)',
+ ' "dbrepllag" - Returns database server with the highest replication lag',
+ ),
+ 'filteriw' => 'Return only local or only nonlocal entries of the interwiki map',
+ 'showalldb' => 'List all database servers, not just the one lagging the most',
+ );
+ }
+
+ protected function getDescription() {
+ return 'Return general information about the site.';
+ }
+
+ protected function getExamples() {
+ return array(
+ 'api.php?action=query&meta=siteinfo&siprop=general|namespaces|statistics',
+ 'api.php?action=query&meta=siteinfo&siprop=interwikimap&sifilteriw=local',
+ 'api.php?action=query&meta=siteinfo&siprop=dbrepllag&sishowalldb',
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
--- /dev/null
+<?php
+
+/*
+ * Created on Oct 16, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+/**
+ * This query action adds a list of a specified user's contributions to the output.
+ *
+ * @addtogroup API
+ */
+class ApiQueryContributions extends ApiQueryBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'uc');
+ }
+
+ private $params, $username;
+ private $fld_ids = false, $fld_title = false, $fld_timestamp = false,
+ $fld_comment = false, $fld_flags = false;
+
+ public function execute() {
+
+ // Parse some parameters
+ $this->params = $this->extractRequestParams();
+
+ $prop = array_flip($this->params['prop']);
+ $this->fld_ids = isset($prop['ids']);
+ $this->fld_title = isset($prop['title']);
+ $this->fld_comment = isset($prop['comment']);
+ $this->fld_flags = isset($prop['flags']);
+ $this->fld_timestamp = isset($prop['timestamp']);
+
+ // TODO: if the query is going only against the revision table, should this be done?
+ $this->selectNamedDB('contributions', DB_SLAVE, 'contributions');
+ $db = $this->getDB();
+
+ // Prepare query
+ $this->prepareUsername();
+ $this->prepareQuery();
+
+ //Do the actual query.
+ $res = $this->select( __METHOD__ );
+
+ //Initialise some variables
+ $data = array ();
+ $count = 0;
+ $limit = $this->params['limit'];
+
+ //Fetch each row
+ while ( $row = $db->fetchObject( $res ) ) {
+ if (++ $count > $limit) {
+ // We've reached the one extra which shows that there are additional pages to be had. Stop here...
+ $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->rev_timestamp));
+ break;
+ }
+
+ $vals = $this->extractRowInfo($row);
+ if ($vals)
+ $data[] = $vals;
+ }
+
+ //Free the database record so the connection can get on with other stuff
+ $db->freeResult($res);
+
+ //And send the whole shebang out as output.
+ $this->getResult()->setIndexedTagName($data, 'item');
+ $this->getResult()->addValue('query', $this->getModuleName(), $data);
+ }
+
+ /**
+ * Validate the 'user' parameter and set the value to compare
+ * against `revision`.`rev_user_text`
+ */
+ private function prepareUsername() {
+ $user = $this->params['user'];
+ if( $user ) {
+ $name = User::isIP( $user )
+ ? $user
+ : User::getCanonicalName( $user, 'valid' );
+ if( $name === false ) {
+ $this->dieUsage( "User name {$user} is not valid", 'param_user' );
+ } else {
+ $this->username = $name;
+ }
+ } else {
+ $this->dieUsage( 'User parameter may not be empty', 'param_user' );
+ }
+ }
+
+ /**
+ * Prepares the query and returns the limit of rows requested
+ */
+ private function prepareQuery() {
+
+ //We're after the revision table, and the corresponding page row for
+ //anything we retrieve.
+ list ($tbl_page, $tbl_revision) = $this->getDB()->tableNamesN('page', 'revision');
+ $this->addTables("$tbl_revision LEFT OUTER JOIN $tbl_page ON page_id=rev_page");
+
+ $this->addWhereFld('rev_deleted', 0);
+
+ // We only want pages by the specified user.
+ $this->addWhereFld( 'rev_user_text', $this->username );
+
+ // ... and in the specified timeframe.
+ $this->addWhereRange('rev_timestamp',
+ $this->params['dir'], $this->params['start'], $this->params['end'] );
+
+ $this->addWhereFld('page_namespace', $this->params['namespace']);
+
+ $show = $this->params['show'];
+ if (!is_null($show)) {
+ $show = array_flip($show);
+ if (isset ($show['minor']) && isset ($show['!minor']))
+ $this->dieUsage("Incorrect parameter - mutually exclusive values may not be supplied", 'show');
+
+ $this->addWhereIf('rev_minor_edit = 0', isset ($show['!minor']));
+ $this->addWhereIf('rev_minor_edit != 0', isset ($show['minor']));
+ }
+
+ $this->addOption('LIMIT', $this->params['limit'] + 1);
+
+ // Mandatory fields: timestamp allows request continuation
+ // ns+title checks if the user has access rights for this page
+ $this->addFields(array(
+ 'rev_timestamp',
+ 'page_namespace',
+ 'page_title',
+ ));
+
+ $this->addFieldsIf('rev_page', $this->fld_ids);
+ $this->addFieldsIf('rev_id', $this->fld_ids);
+ // $this->addFieldsIf('rev_text_id', $this->fld_ids); // Should this field be exposed?
+ $this->addFieldsIf('rev_comment', $this->fld_comment);
+ $this->addFieldsIf('rev_minor_edit', $this->fld_flags);
+
+ // These fields depend only work if the page table is joined
+ $this->addFieldsIf('page_is_new', $this->fld_flags);
+ }
+
+ /**
+ * Extract fields from the database row and append them to a result array
+ */
+ private function extractRowInfo($row) {
+
+ $vals = array();
+
+ if ($this->fld_ids) {
+ $vals['pageid'] = intval($row->rev_page);
+ $vals['revid'] = intval($row->rev_id);
+ // $vals['textid'] = intval($row->rev_text_id); // todo: Should this field be exposed?
+ }
+
+ if ($this->fld_title)
+ ApiQueryBase :: addTitleInfo($vals,
+ Title :: makeTitle($row->page_namespace, $row->page_title));
+
+ if ($this->fld_timestamp)
+ $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->rev_timestamp);
+
+ if ($this->fld_flags) {
+ if ($row->page_is_new)
+ $vals['new'] = '';
+ if ($row->rev_minor_edit)
+ $vals['minor'] = '';
+ }
+
+ if ($this->fld_comment && !empty ($row->rev_comment))
+ $vals['comment'] = $row->rev_comment;
+
+ return $vals;
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'limit' => array (
+ ApiBase :: PARAM_DFLT => 10,
+ ApiBase :: PARAM_TYPE => 'limit',
+ ApiBase :: PARAM_MIN => 1,
+ ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+ ),
+ 'start' => array (
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'end' => array (
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'user' => array (
+ ApiBase :: PARAM_TYPE => 'user'
+ ),
+ 'dir' => array (
+ ApiBase :: PARAM_DFLT => 'older',
+ ApiBase :: PARAM_TYPE => array (
+ 'newer',
+ 'older'
+ )
+ ),
+ 'namespace' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => 'namespace'
+ ),
+ 'prop' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_DFLT => 'ids|title|timestamp|flags|comment',
+ ApiBase :: PARAM_TYPE => array (
+ 'ids',
+ 'title',
+ 'timestamp',
+ 'comment',
+ 'flags'
+ )
+ ),
+ 'show' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => array (
+ 'minor',
+ '!minor',
+ )
+ ),
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'limit' => 'The maximum number of contributions to return.',
+ 'start' => 'The start timestamp to return from.',
+ 'end' => 'The end timestamp to return to.',
+ 'user' => 'The user to retrieve contributions for.',
+ 'dir' => 'The direction to search (older or newer).',
+ 'namespace' => 'Only list contributions in these namespaces',
+ 'prop' => 'Include additional pieces of information',
+ 'show' => 'Show only items that meet this criteria, e.g. non minor edits only: show=!minor',
+ );
+ }
+
+ protected function getDescription() {
+ return 'Get all edits by a user';
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=query&list=usercontribs&ucuser=YurikBot'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+
--- /dev/null
+<?php
+
+/*
+ * Created on July 30, 2007
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2007 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+/**
+ * Query module to get information about the currently logged-in user
+ *
+ * @addtogroup API
+ */
+class ApiQueryUserInfo extends ApiQueryBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'ui');
+ }
+
+ public function execute() {
+
+ global $wgUser;
+
+ $params = $this->extractRequestParams();
+ $result = $this->getResult();
+
+ $vals = array();
+ $vals['name'] = $wgUser->getName();
+
+ if( $wgUser->isAnon() ) $vals['anon'] = '';
+
+ if (!is_null($params['prop'])) {
+ $prop = array_flip($params['prop']);
+ if (isset($prop['blockinfo'])) {
+ if ($wgUser->isBlocked()) {
+ $vals['blockedby'] = User::whoIs($wgUser->blockedBy());
+ $vals['blockreason'] = $wgUser->blockedFor();
+ }
+ }
+ if (isset($prop['hasmsg']) && $wgUser->getNewtalk()) {
+ $vals['messages'] = '';
+ }
+ if (isset($prop['groups'])) {
+ $vals['groups'] = $wgUser->getGroups();
+ $result->setIndexedTagName($vals['groups'], 'g'); // even if empty
+ }
+ if (isset($prop['rights'])) {
+ $vals['rights'] = $wgUser->getRights();
+ $result->setIndexedTagName($vals['rights'], 'r'); // even if empty
+ }
+ if (isset($prop['options'])) {
+ $vals['options'] = (is_null($wgUser->mOptions) ? User::getDefaultOptions() : $wgUser->mOptions);
+ }
+ }
+
+ $result->addValue(null, $this->getModuleName(), $vals);
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'prop' => array (
+ ApiBase :: PARAM_DFLT => NULL,
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => array (
+ 'blockinfo',
+ 'hasmsg',
+ 'groups',
+ 'rights',
+ 'options'
+ ))
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'prop' => array(
+ 'What pieces of information to include',
+ ' blockinfo - tags if the user is blocked, by whom, and for what reason',
+ ' hasmsg - adds a tag "message" if user has pending messages',
+ ' groups - lists all the groups the current user belongs to',
+ ' rights - lists of all rights the current user has',
+ ' options - lists all preferences the current user has set'
+ )
+ );
+ }
+
+ protected function getDescription() {
+ return 'Get information about the current user';
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=query&meta=userinfo',
+ 'api.php?action=query&meta=userinfo&uiprop=blockinfo|groups|rights|hasmsg',
+ 'api.php?action=query&meta=userinfo&uioption=rememberpassword',
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+
--- /dev/null
+<?php
+
+/*
+ * Created on Sep 25, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+/**
+ * This query action allows clients to retrieve a list of recently modified pages
+ * that are part of the logged-in user's watchlist.
+ *
+ * @addtogroup API
+ */
+class ApiQueryWatchlist extends ApiQueryGeneratorBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'wl');
+ }
+
+ public function execute() {
+ $this->run();
+ }
+
+ public function executeGenerator($resultPageSet) {
+ $this->run($resultPageSet);
+ }
+
+ private $fld_ids = false, $fld_title = false, $fld_patrol = false, $fld_flags = false,
+ $fld_timestamp = false, $fld_user = false, $fld_comment = false, $fld_sizes = false;
+
+ private function run($resultPageSet = null) {
+ global $wgUser, $wgDBtype;
+
+ $this->selectNamedDB('watchlist', DB_SLAVE, 'watchlist');
+
+ if (!$wgUser->isLoggedIn())
+ $this->dieUsage('You must be logged-in to have a watchlist', 'notloggedin');
+
+ $allrev = $start = $end = $namespace = $dir = $limit = $prop = null;
+ extract($this->extractRequestParams());
+
+ if (!is_null($prop) && is_null($resultPageSet)) {
+
+ $prop = array_flip($prop);
+
+ $this->fld_ids = isset($prop['ids']);
+ $this->fld_title = isset($prop['title']);
+ $this->fld_flags = isset($prop['flags']);
+ $this->fld_user = isset($prop['user']);
+ $this->fld_comment = isset($prop['comment']);
+ $this->fld_timestamp = isset($prop['timestamp']);
+ $this->fld_sizes = isset($prop['sizes']);
+ $this->fld_patrol = isset($prop['patrol']);
+
+ if ($this->fld_patrol) {
+ global $wgUseRCPatrol, $wgUser;
+ if (!$wgUseRCPatrol || !$wgUser->isAllowed('patrol'))
+ $this->dieUsage('patrol property is not available', 'patrol');
+ }
+ }
+
+ if (is_null($resultPageSet)) {
+ $this->addFields(array (
+ 'rc_cur_id',
+ 'rc_this_oldid',
+ 'rc_namespace',
+ 'rc_title',
+ 'rc_timestamp'
+ ));
+
+ $this->addFieldsIf('rc_new', $this->fld_flags);
+ $this->addFieldsIf('rc_minor', $this->fld_flags);
+ $this->addFieldsIf('rc_user', $this->fld_user);
+ $this->addFieldsIf('rc_user_text', $this->fld_user);
+ $this->addFieldsIf('rc_comment', $this->fld_comment);
+ $this->addFieldsIf('rc_patrolled', $this->fld_patrol);
+ $this->addFieldsIf('rc_old_len', $this->fld_sizes);
+ $this->addFieldsIf('rc_new_len', $this->fld_sizes);
+ }
+ elseif ($allrev) {
+ $this->addFields(array (
+ 'rc_this_oldid',
+ 'rc_namespace',
+ 'rc_title',
+ 'rc_timestamp'
+ ));
+ } else {
+ $this->addFields(array (
+ 'rc_cur_id',
+ 'rc_namespace',
+ 'rc_title',
+ 'rc_timestamp'
+ ));
+ }
+
+ $this->addTables(array (
+ 'watchlist',
+ 'page',
+ 'recentchanges'
+ ));
+
+ $userId = $wgUser->getID();
+ $this->addWhere(array (
+ 'wl_namespace = rc_namespace',
+ 'wl_title = rc_title',
+ 'rc_cur_id = page_id',
+ 'wl_user' => $userId,
+ 'rc_deleted' => 0,
+ ));
+
+ $this->addWhereRange('rc_timestamp', $dir, $start, $end);
+ $this->addWhereFld('wl_namespace', $namespace);
+ $this->addWhereIf('rc_this_oldid=page_latest', !$allrev);
+
+ # This is a index optimization for mysql, as done in the Special:Watchlist page
+ $this->addWhereIf("rc_timestamp > ''", !isset ($start) && !isset ($end) && $wgDBtype == 'mysql');
+
+ $this->addOption('LIMIT', $limit +1);
+
+ $data = array ();
+ $count = 0;
+ $res = $this->select(__METHOD__);
+
+ $db = $this->getDB();
+ while ($row = $db->fetchObject($res)) {
+ if (++ $count > $limit) {
+ // We've reached the one extra which shows that there are additional pages to be had. Stop here...
+ $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->rc_timestamp));
+ break;
+ }
+
+ if (is_null($resultPageSet)) {
+ $vals = $this->extractRowInfo($row);
+ if ($vals)
+ $data[] = $vals;
+ } else {
+ if ($allrev) {
+ $data[] = intval($row->rc_this_oldid);
+ } else {
+ $data[] = intval($row->rc_cur_id);
+ }
+ }
+ }
+
+ $db->freeResult($res);
+
+ if (is_null($resultPageSet)) {
+ $this->getResult()->setIndexedTagName($data, 'item');
+ $this->getResult()->addValue('query', $this->getModuleName(), $data);
+ }
+ elseif ($allrev) {
+ $resultPageSet->populateFromRevisionIDs($data);
+ } else {
+ $resultPageSet->populateFromPageIDs($data);
+ }
+ }
+
+ private function extractRowInfo($row) {
+
+ $vals = array ();
+
+ if ($this->fld_ids) {
+ $vals['pageid'] = intval($row->rc_cur_id);
+ $vals['revid'] = intval($row->rc_this_oldid);
+ }
+
+ if ($this->fld_title)
+ ApiQueryBase :: addTitleInfo($vals, Title :: makeTitle($row->rc_namespace, $row->rc_title));
+
+ if ($this->fld_user) {
+ $vals['user'] = $row->rc_user_text;
+ if (!$row->rc_user)
+ $vals['anon'] = '';
+ }
+
+ if ($this->fld_flags) {
+ if ($row->rc_new)
+ $vals['new'] = '';
+ if ($row->rc_minor)
+ $vals['minor'] = '';
+ }
+
+ if ($this->fld_patrol && isset($row->rc_patrolled))
+ $vals['patrolled'] = '';
+
+ if ($this->fld_timestamp)
+ $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->rc_timestamp);
+
+ $this->addFieldsIf('rc_new_len', $this->fld_sizes);
+
+ if ($this->fld_sizes) {
+ $vals['oldlen'] = intval($row->rc_old_len);
+ $vals['newlen'] = intval($row->rc_new_len);
+ }
+
+ if ($this->fld_comment && !empty ($row->rc_comment))
+ $vals['comment'] = $row->rc_comment;
+
+ return $vals;
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'allrev' => false,
+ 'start' => array (
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'end' => array (
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'namespace' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => 'namespace'
+ ),
+ 'dir' => array (
+ ApiBase :: PARAM_DFLT => 'older',
+ ApiBase :: PARAM_TYPE => array (
+ 'newer',
+ 'older'
+ )
+ ),
+ 'limit' => array (
+ ApiBase :: PARAM_DFLT => 10,
+ ApiBase :: PARAM_TYPE => 'limit',
+ ApiBase :: PARAM_MIN => 1,
+ ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+ ),
+ 'prop' => array (
+ APIBase :: PARAM_ISMULTI => true,
+ APIBase :: PARAM_DFLT => 'ids|title|flags',
+ APIBase :: PARAM_TYPE => array (
+ 'ids',
+ 'title',
+ 'flags',
+ 'user',
+ 'comment',
+ 'timestamp',
+ 'patrol',
+ 'sizes',
+ )
+ )
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'allrev' => 'Include multiple revisions of the same page within given timeframe.',
+ 'start' => 'The timestamp to start enumerating from.',
+ 'end' => 'The timestamp to end enumerating.',
+ 'namespace' => 'Filter changes to only the given namespace(s).',
+ 'dir' => 'In which direction to enumerate pages.',
+ 'limit' => 'How many total pages to return per request.',
+ 'prop' => 'Which additional items to get (non-generator mode only).'
+ );
+ }
+
+ protected function getDescription() {
+ return '';
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=query&list=watchlist',
+ 'api.php?action=query&list=watchlist&wlprop=ids|title|timestamp|user|comment',
+ 'api.php?action=query&list=watchlist&wlallrev&wlprop=ids|title|timestamp|user|comment',
+ 'api.php?action=query&generator=watchlist&prop=info',
+ 'api.php?action=query&generator=watchlist&gwlallrev&prop=revisions&rvprop=timestamp|user'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+
--- /dev/null
+<?php
+
+/*
+ * Created on Jun 20, 2007
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ("ApiBase.php");
+}
+
+/**
+ * @addtogroup API
+ */
+class ApiRollback extends ApiBase {
+
+ public function __construct($main, $action) {
+ parent :: __construct($main, $action);
+ }
+
+ public function execute() {
+ global $wgUser;
+ $this->getMain()->requestWriteMode();
+ $params = $this->extractRequestParams();
+
+ $titleObj = NULL;
+ if(!isset($params['title']))
+ $this->dieUsage('The title parameter must be set', 'notitle');
+ if(!isset($params['user']))
+ $this->dieUsage('The user parameter must be set', 'nouser');
+ if(!isset($params['token']))
+ $this->dieUsage('The token parameter must be set', 'notoken');
+
+ // doRollback() also checks for these, but we wanna save some work
+ if($wgUser->isBlocked())
+ $this->dieUsage('You have been blocked from editing', 'blocked');
+ if(wfReadOnly())
+ $this->dieUsage('The wiki is in read-only mode', 'readonly');
+
+ $titleObj = Title::newFromText($params['title']);
+ if(!$titleObj)
+ $this->dieUsage("Bad title ``{$params['title']}''", 'invalidtitle');
+ if(!$titleObj->userCan('rollback'))
+ $this->dieUsage('You don\'t have permission to rollback', 'permissiondenied');
+
+ $username = User::getCanonicalName($params['user']);
+ if(!$username)
+ $this->dieUsage("Invalid username ``{$params['user']}''", 'invaliduser');
+
+ $articleObj = new Article($titleObj);
+ $summary = (isset($params['summary']) ? $params['summary'] : "");
+ $details = NULL;
+ $dbw = wfGetDb(DB_MASTER);
+ $dbw->begin();
+ $retval = $articleObj->doRollback($username, $summary, $params['token'], $params['markbot'], &$details);
+
+ switch($retval)
+ {
+ case Article::SUCCESS:
+ break; // We'll deal with that later
+ case Article::PERM_DENIED:
+ $this->dieUsage("You don't have permission to rollback", 'permissiondenied');
+ case Article::BLOCKED: // If we get BLOCKED or PERM_DENIED that's very weird, but it's possible
+ $this->dieUsage('You have been blocked from editing', 'blocked');
+ case Article::READONLY:
+ $this->dieUsage('The wiki is in read-only mode', 'readonly');
+ case Article::BAD_TOKEN:
+ $this->dieUsage('Invalid token', 'badtoken');
+ case Article::BAD_TITLE:
+ $this->dieUsage("``{$params['title']}'' doesn't exist", 'missingtitle');
+ case Article::ALREADYROLLED:
+ $current = $details['current'];
+ $currentID = $current->getId();
+ $this->dieUsage("The edit(s) you tried to rollback is/are already rolled back." .
+ "The current revision ID is ``$currentID''", 'alreadyrolled');
+ case Article::ONLY_AUTHOR:
+ $this->dieUsage("User ``$username'' is the only author of the page", 'onlyauthor');
+ case Article::RATE_LIMITED:
+ $this->dieUsage("You can't rollback too many articles in too short a time. Please wait a little while and try again", 'ratelimited');
+ default:
+ // rollback() has apparently invented a new error, which is extremely weird
+ $this->dieDebug(__METHOD__, "rollback() returned an unknown error ($retval)");
+ }
+ // $retval has to be Article::SUCCESS if we get here
+ $dbw->commit();
+ $current = $target = $summary = NULL;
+ extract($details);
+
+ $info = array(
+ 'title' => $titleObj->getPrefixedText(),
+ 'pageid' => $current->getPage(),
+ 'summary' => $summary,
+ 'revid' => $titleObj->getLatestRevID(),
+ 'old_revid' => $current->getID(),
+ 'last_revid' => $target->getID()
+ );
+
+ $this->getResult()->addValue(null, $this->getModuleName(), $info);
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'title' => null,
+ 'user' => null,
+ 'token' => null,
+ 'summary' => null,
+ 'markbot' => false
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'title' => 'Title of the page you want to rollback.',
+ 'user' => 'Name of the user whose edits are to be rolled back. If set incorrectly, you\'ll get a badtoken error.',
+ 'token' => 'A rollback token previously retrieved through prop=info',
+ 'summary' => 'Custom edit summary. If not set, default summary will be used.',
+ 'markbot' => 'Mark the reverted edits and the revert as bot edits'
+ );
+ }
+
+ protected function getDescription() {
+ return array(
+ 'Undoes the last edit to the page. If the last user who edited the page made multiple edits in a row,',
+ 'they will all be rolled back. You need to be logged in as a sysop to use this function, see also action=login.'
+ );
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=rollback&title=Main%20Page&user=Catrope&token=123ABC',
+ 'api.php?action=rollback&title=Main%20Page&user=217.121.114.116&token=123ABC&summary=Reverting%20vandalism&markbot=1'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
--- /dev/null
+<?php
+
+/*
+ * Created on Sep 7, 2007
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ("ApiBase.php");
+}
+
+/**
+ * @addtogroup API
+ */
+class ApiUnblock extends ApiBase {
+
+ public function __construct($main, $action) {
+ parent :: __construct($main, $action);
+ }
+
+ public function execute() {
+ global $wgUser;
+ $this->getMain()->requestWriteMode();
+ $params = $this->extractRequestParams();
+
+ if($params['gettoken'])
+ {
+ $res['unblocktoken'] = $wgUser->editToken();
+ $this->getResult()->addValue(null, $this->getModuleName(), $res);
+ return;
+ }
+
+ if(is_null($params['id']) && is_null($params['user']))
+ $this->dieUsage('Either the id or the user parameter must be set', 'notarget');
+ if(!is_null($params['id']) && !is_null($params['user']))
+ $this->dieUsage('The id and user parameters can\'t be used together', 'idanduser');
+ if(is_null($params['token']))
+ $this->dieUsage('The token parameter must be set', 'notoken');
+ if(!$wgUser->matchEditToken($params['token']))
+ $this->dieUsage('Invalid token', 'badtoken');
+ if(!$wgUser->isAllowed('block'))
+ $this->dieUsage('You don\'t have permission to unblock users', 'permissiondenied');
+ if(wfReadOnly())
+ $this->dieUsage('The wiki is in read-only mode', 'readonly');
+
+ $id = $params['id'];
+ $user = $params['user'];
+ $reason = $params['reason'];
+ $dbw = wfGetDb(DB_MASTER);
+ $dbw->begin();
+ $retval = IPUnblockForm::doUnblock(&$id, &$user, &$reason, &$range);
+
+ switch($retval)
+ {
+ case IPUnblockForm::UNBLOCK_SUCCESS:
+ break; // We'll deal with that later
+ case IPUnblockForm::UNBLOCK_NO_SUCH_ID:
+ $this->dieUsage("There is no block with ID ``$id''", 'nosuchid');
+ case IPUnblockForm::UNBLOCK_USER_NOT_BLOCKED:
+ $this->dieUsage("User ``$user'' is not blocked", 'notblocked');
+ case IPUnblockForm::UNBLOCK_BLOCKED_AS_RANGE:
+ $this->dieUsage("IP address ``$user'' was blocked as part of range ``$range''. You can't unblock the IP invidually, but you can unblock the range as a whole.", 'blockedasrange');
+ case IPUnblockForm::UNBLOCK_UNKNOWNERR:
+ $this->dieUsage("Unknown error", 'unknownerr');
+ default:
+ $this->dieDebug(__METHOD__, "IPBlockForm::doBlock() returned an unknown error ($retval)");
+ }
+ $dbw->commit();
+
+ $res['id'] = $id;
+ $res['user'] = $user;
+ $res['reason'] = $reason;
+ $this->getResult()->addValue(null, $this->getModuleName(), $res);
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'id' => null,
+ 'user' => null,
+ 'token' => null,
+ 'gettoken' => false,
+ 'reason' => null,
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'id' => 'ID of the block you want to unblock (obtained through list=blocks). Cannot be user together with user',
+ 'user' => 'Username, IP address or IP range you want to unblock. Cannot be used together with id',
+ 'token' => 'An unblock token previously obtained through the gettoken parameter',
+ 'gettoken' => 'If set, an unblock token will be returned, and no other action will be taken',
+ 'reason' => 'Reason for unblock (optional)',
+ );
+ }
+
+ protected function getDescription() {
+ return array(
+ 'Unblock a user.'
+ );
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=unblock&id=105',
+ 'api.php?action=unblock&user=Bob&reason=Sorry%20Bob'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
--- /dev/null
+<?php
+
+/*
+ * Created on Jul 3, 2007
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ("ApiBase.php");
+}
+
+/**
+ * @addtogroup API
+ */
+class ApiUndelete extends ApiBase {
+
+ public function __construct($main, $action) {
+ parent :: __construct($main, $action);
+ }
+
+ public function execute() {
+ global $wgUser;
+ $this->getMain()->requestWriteMode();
+ $params = $this->extractRequestParams();
+
+ $titleObj = NULL;
+ if(!isset($params['title']))
+ $this->dieUsage('The title parameter must be set', 'notitle');
+ if(!isset($params['token']))
+ $this->dieUsage('The token parameter must be set', 'notoken');
+
+ if(!$wgUser->isAllowed('undelete'))
+ $this->dieUsage('You don\'t have permission to restore deleted revisions', 'permissiondenied');
+ if($wgUser->isBlocked())
+ $this->dieUsage('You have been blocked from editing', 'blocked');
+ if(wfReadOnly())
+ $this->dieUsage('The wiki is in read-only mode', 'readonly');
+ if(!$wgUser->matchEditToken($params['token']))
+ $this->dieUsage('Invalid token', 'badtoken');
+
+ $titleObj = Title::newFromText($params['title']);
+ if(!$titleObj)
+ $this->dieUsage("Bad title ``{$params['title']}''", 'invalidtitle');
+
+ // Convert timestamps
+ if(!is_array($params['timestamps']))
+ $params['timestamps'] = array($params['timestamps']);
+ foreach($params['timestamps'] as $i => $ts)
+ $params['timestamps'][$i] = wfTimestamp(TS_MW, $ts);
+
+ $pa = new PageArchive($titleObj);
+ $dbw = wfGetDb(DB_MASTER);
+ $dbw->begin();
+ $retval = $pa->undelete((isset($params['timestamps']) ? $params['timestamps'] : array()), $params['reason']);
+ if(!is_array($retval))
+ switch($retval)
+ {
+ case PageArchive::UNDELETE_NOTHINGRESTORED:
+ $this->dieUsage('No revisions could be restored', 'norevs');
+ case PageArchive::UNDELETE_NOTAVAIL:
+ $this->dieUsage('Not all requested revisions could be found', 'revsnotfound');
+ case PageArchive::UNDELETE_UNKNOWNERR:
+ $this->dieUsage('Undeletion failed with unknown error', 'unknownerror');
+ }
+ $dbw->commit();
+
+ $info['title'] = $titleObj->getPrefixedText();
+ $info['revisions'] = $retval[0];
+ $info['fileversions'] = $retval[1];
+ $info['reason'] = $retval[2];
+ $this->getResult()->addValue(null, $this->getModuleName(), $info);
+ }
+
+ protected function getAllowedParams() {
+ return array (
+ 'title' => null,
+ 'token' => null,
+ 'reason' => "",
+ 'timestamps' => array(
+ ApiBase :: PARAM_ISMULTI => true
+ )
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'title' => 'Title of the page you want to restore.',
+ 'token' => 'An undelete token previously retrieved through list=deletedrevs',
+ 'reason' => 'Reason for restoring (optional)',
+ 'timestamps' => 'Timestamps of the revisions to restore. If not set, all revisions will be restored.'
+ );
+ }
+
+ protected function getDescription() {
+ return array(
+ 'Restore certain revisions of a deleted page. A list of deleted revisions (including timestamps) can be',
+ 'retrieved through list=deletedrevs'
+ );
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=undelete&title=Main%20Page&token=123ABC&reason=Restoring%20main%20page',
+ 'api.php?action=undelete&title=Main%20Page&token=123ABC×tamps=20070703220045|20070702194856'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+++ /dev/null
-<?php
-
-/*
- * Created on Sep 4, 2007
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
-}
-
-/**
- * @addtogroup API
- */
-class ApiBlock extends ApiBase {
-
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
- }
-
- public function execute() {
- global $wgUser;
- $this->getMain()->requestWriteMode();
- $params = $this->extractRequestParams();
-
- if($params['gettoken'])
- {
- $res['blocktoken'] = $wgUser->editToken();
- $this->getResult()->addValue(null, $this->getModuleName(), $res);
- return;
- }
-
- if(is_null($params['user']))
- $this->dieUsage('The user parameter must be set', 'nouser');
- if(is_null($params['token']))
- $this->dieUsage('The token parameter must be set', 'notoken');
- if(!$wgUser->matchEditToken($params['token']))
- $this->dieUsage('Invalid token', 'badtoken');
- if(!$wgUser->isAllowed('block'))
- $this->dieUsage('You don\'t have permission to block users', 'permissiondenied');
- if($params['hidename'] && !$wgUser->isAllowed('hideuser'))
- $this->dieUsage('You don\'t have permission to hide user names from the block log', 'nohide');
- if(wfReadOnly())
- $this->dieUsage('The wiki is in read-only mode', 'readonly');
-
- $form = new IPBlockForm('');
- $form->BlockAddress = $params['user'];
- $form->BlockReason = $params['reason'];
- $form->BlockReasonList = 'other';
- $form->BlockExpiry = ($params['expiry'] == 'never' ? 'infinite' : $params['expiry']);
- $form->BlockOther = '';
- $form->BlockAnonOnly = $params['anononly'];
- $form->BlockCreateAccount = $params['nocreate'];
- $form->BlockEnableAutoBlock = $params['autoblock'];
- $form->BlockEmail = $params['noemail'];
- $form->BlockHideName = $params['hidename'];
-
- $dbw = wfGetDb(DB_MASTER);
- $dbw->begin();
- $retval = $form->doBlock($userID, $expiry);
- switch($retval)
- {
- case IPBlockForm::BLOCK_SUCCESS:
- break; // We'll deal with that later
- case IPBlockForm::BLOCK_RANGE_INVALID:
- $this->dieUsage("Invalid IP range ``{$params['user']}''", 'invalidrange');
- case IPBlockForm::BLOCK_RANGE_DISABLED:
- $this->dieUsage('Blocking IP ranges has been disabled', 'rangedisabled');
- case IPBlockForm::BLOCK_NONEXISTENT_USER:
- $this->dieUsage("User ``{$params['user']}'' doesn't exist", 'nosuchuser');
- case IPBlockForm::BLOCK_IP_INVALID:
- $this->dieUsage("Invaild IP address ``{$params['user']}''", 'invalidip');
- case IPBlockForm::BLOCK_EXPIRY_INVALID:
- $this->dieUsage("Invalid expiry time ``{$params['expiry']}''", 'invalidexpiry');
- case IPBlockForm::BLOCK_ALREADY_BLOCKED:
- $this->dieUsage("User ``{$params['user']}'' is already blocked", 'alreadyblocked');
- default:
- $this->dieDebug(__METHOD__, "IPBlockForm::doBlock() returned an unknown error ($retval)");
- }
- $dbw->commit();
-
- $res['user'] = $params['user'];
- $res['userID'] = $userID;
- $res['expiry'] = ($expiry == Block::infinity() ? 'infinite' : $expiry);
- $res['reason'] = $params['reason'];
- if($params['anononly'])
- $res['anononly'] = '';
- if($params['nocreate'])
- $res['nocreate'] = '';
- if($params['autoblock'])
- $res['autoblock'] = '';
- if($params['noemail'])
- $res['noemail'] = '';
- if($params['hidename'])
- $res['hidename'] = '';
-
- $this->getResult()->addValue(null, $this->getModuleName(), $res);
- }
-
- protected function getAllowedParams() {
- return array (
- 'user' => null,
- 'token' => null,
- 'gettoken' => false,
- 'expiry' => 'never',
- 'reason' => null,
- 'anononly' => false,
- 'nocreate' => false,
- 'autoblock' => false,
- 'noemail' => false,
- 'hidename' => false,
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'user' => 'Username, IP address or IP range you want to block',
- 'token' => 'A block token previously obtained through the gettoken parameter',
- 'gettoken' => 'If set, a block token will be returned, and no other action will be taken',
- 'expiry' => 'Relative expiry time, e.g. \'5 months\' or \'2 weeks\'. If set to \'infinite\', \'indefinite\' or \'never\', the block will never expire.',
- 'reason' => 'Reason for block (optional)',
- 'anononly' => 'Block anonymous users only (i.e. disable anonymous edits for this IP)',
- 'nocreate' => 'Prevent account creation',
- 'autoblock' => 'Automatically block the last used IP address, and any subsequent IP addresses they try to login from',
- 'noemail' => 'Prevent user from sending e-mail through the wiki',
- 'hidename' => 'Hide the username from the block log.'
- );
- }
-
- protected function getDescription() {
- return array(
- 'Block a user.'
- );
- }
-
- protected function getExamples() {
- return array (
- 'api.php?action=block&user=123.5.5.12&expiry=3%20days&reason=First%20strike',
- 'api.php?action=block&user=Vandal&expiry=never&reason=Vandalism&nocreate&autoblock&noemail'
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiBlock.php 28209 2007-12-06 16:06:22Z vasilievvv $';
- }
-}
+++ /dev/null
-<?php
-
-/*
- * Created on Sep 11, 2007
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
-}
-
-/**
- * @addtogroup API
- */
-class ApiChangeRights extends ApiBase {
-
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
- }
-
- public function execute() {
- global $wgUser, $wgRequest;
- $this->getMain()->requestWriteMode();
-
- if(wfReadOnly())
- $this->dieUsage('The wiki is in read-only mode', 'readonly');
- $params = $this->extractRequestParams();
-
- $ur = new UserrightsForm($wgRequest);
- $allowed = $ur->changeableGroups();
- $res = array();
-
- if(is_null($params['user']))
- $this->dieUsage('The user parameter must be set', 'nouser');
-
- $uName = User::getCanonicalName($params['user']);
- $u = User::newFromName($uName);
- if(!$u)
- $this->dieUsage("Invalid username ``{$params['user']}''", 'invaliduser');
- if($u->getId() == 0) // Anon or non-existent
- $this->dieUsage("User ``{$params['user']}'' doesn't exist", 'nosuchuser');
-
- $curgroups = $u->getGroups();
-
- if($params['listgroups'])
- {
- $res['user'] = $uName;
- $res['allowedgroups'] = $allowed;
- $res['ingroups'] = $curgroups;
- $this->getResult()->setIndexedTagName($res['ingroups'], 'group');
- $this->getResult()->setIndexedTagName($res['allowedgroups']['add'], 'group');
- $this->getResult()->setIndexedTagName($res['allowedgroups']['remove'], 'group');
- }
-;
- if($params['gettoken'])
- {
- $res['changerightstoken'] = $wgUser->editToken($uName);
- $this->getResult()->addValue(null, $this->getModuleName(), $res);
- return;
- }
-
- if(empty($params['addto']) && empty($params['rmfrom']))
- $this->dieUsage('At least one of the addto and rmfrom parameters must be set', 'noaddrm');
- if(is_null($params['token']))
- $this->dieUsage('The token parameter must be set', 'notoken');
- if(!$wgUser->matchEditToken($params['token'], $uName))
- $this->dieUsage('Invalid token', 'badtoken');
-
- if(!$wgUser->isAllowed('userrights'))
- $this->dieUsage('You don\'t have permission to change users\' rights', 'permissiondenied');
-
- // First let's remove redundant groups and check permissions while we're at it
- if(is_null($params['addto']))
- $params['addto'] = array();
- $addto = array();
- foreach($params['addto'] as $g)
- {
- if(!in_array($g, $allowed['add']))
- $this->dieUsage("You don't have permission to add to group ``$g''", 'cantadd');
- if(!in_array($g, $curgroups))
- $addto[] = $g;
- }
-
- if(is_null($params['rmfrom']))
- $params['rmfrom'] = array();
- $rmfrom = array();
- foreach($params['rmfrom'] as $g)
- {
- if(!in_array($g, $allowed['remove']))
- $this->dieUsage("You don't have permission to remove from group ``$g''", 'cantremove');
- if(in_array($g, $curgroups))
- $rmfrom[] = $g;
- }
- $dbw = wfGetDb(DB_MASTER);
- $dbw->begin();
- $ur->doSaveUserGroups($u, $rmfrom, $addto, $params['reason']);
- $dbw->commit();
- $res['user'] = $uName;
- $res['addedto'] = $addto;
- $res['removedfrom'] = $rmfrom;
- $res['reason'] = $params['reason'];
-
- $this->getResult()->setIndexedTagName($res['addedto'], 'group');
- $this->getResult()->setIndexedTagName($res['removedfrom'], 'group');
- $this->getResult()->addValue(null, $this->getModuleName(), $res);
- }
-
- protected function getAllowedParams() {
- return array (
- 'user' => null,
- 'token' => null,
- 'gettoken' => false,
- 'listgroups' => false,
- 'addto' => array(
- ApiBase :: PARAM_ISMULTI => true,
- ),
- 'rmfrom' => array(
- ApiBase :: PARAM_ISMULTI => true,
- ),
- 'reason' => ''
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'user' => 'The user you want to add to or remove from groups.',
- 'token' => 'A changerights token previously obtained through the gettoken parameter.',
- 'gettoken' => 'Output a token. Note that the user parameter still has to be set.',
- 'listgroups' => 'List the groups the user is in, and the ones you can add them to and remove them from.',
- 'addto' => 'Pipe-separated list of groups to add this user to',
- 'rmfrom' => 'Pipe-separated list of groups to remove this user from',
- 'reason' => 'Reason for change (optional)'
- );
- }
-
- protected function getDescription() {
- return array(
- 'Add or remove a user from certain groups.'
- );
- }
-
- protected function getExamples() {
- return array (
- 'api.php?action=changerights&user=Bob&gettoken&listgroups',
- 'api.php?action=changerights&user=Bob&token=123ABC&addto=sysop&reason=Promoting%20per%20RFA'
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiChangeRights.php 28209 2007-12-06 16:06:22Z vasilievvv $';
- }
-}
+++ /dev/null
-<?php
-
-/*
- * Created on Jun 30, 2007
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
-}
-
-
-/**
- * @addtogroup API
- */
-class ApiDelete extends ApiBase {
-
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
- }
-
- /**
- * We have our own delete() function, since Article.php's implementation is split in two phases
- * @param Article $article - Article object to work on
- * @param string $token - Delete token (same as edit token)
- * @param string $reason - Reason for the deletion. Autogenerated if NULL
- * @return DELETE_SUCCESS on success, DELETE_* on failure
- */
-
- const DELETE_SUCCESS = 0;
- const DELETE_PERM = 1;
- const DELETE_BLOCKED = 2;
- const DELETE_READONLY = 3;
- const DELETE_BADTOKEN = 4;
- const DELETE_BADARTICLE = 5;
-
- public static function delete(&$article, $token, &$reason = NULL)
- {
- global $wgUser;
-
- // Check permissions first
- if(!$article->mTitle->userCan('delete'))
- return self::DELETE_PERM;
- if($wgUser->isBlocked())
- return self::DELETE_BLOCKED;
- if(wfReadOnly())
- return self::DELETE_READONLY;
-
- // Check token
- if(!$wgUser->matchEditToken($token))
- return self::DELETE_BADTOKEN;
-
- // Auto-generate a summary, if necessary
- if(is_null($reason))
- {
- $reason = $article->generateReason($hasHistory);
- if($reason === false)
- return self::DELETE_BADARTICLE;
- }
-
- // Luckily, Article.php provides a reusable delete function that does the hard work for us
- if($article->doDeleteArticle($reason))
- return self::DELETE_SUCCESS;
- return self::DELETE_BADARTICLE;
- }
-
- public function execute() {
- global $wgUser;
- $this->getMain()->requestWriteMode();
- $params = $this->extractRequestParams();
-
- $titleObj = NULL;
- if(!isset($params['title']))
- $this->dieUsage('The title parameter must be set', 'notitle');
- if(!isset($params['token']))
- $this->dieUsage('The token parameter must be set', 'notoken');
-
- // delete() also checks for these, but we wanna save some work
- if(!$wgUser->isAllowed('delete'))
- $this->dieUsage('You don\'t have permission to delete pages', 'permissiondenied');
- if($wgUser->isBlocked())
- $this->dieUsage('You have been blocked from editing', 'blocked');
- if(wfReadOnly())
- $this->dieUsage('The wiki is in read-only mode', 'readonly');
-
- $titleObj = Title::newFromText($params['title']);
- if(!$titleObj)
- $this->dieUsage("Bad title ``{$params['title']}''", 'invalidtitle');
- if(!$titleObj->exists())
- $this->dieUsage("``{$params['title']}'' doesn't exist", 'missingtitle');
-
- $articleObj = new Article($titleObj);
- $reason = (isset($params['reason']) ? $params['reason'] : NULL);
- $dbw = wfGetDb(DB_MASTER);
- $dbw->begin();
- $retval = self::delete(&$articleObj, $params['token'], &$reason);
-
- switch($retval)
- {
- case self::DELETE_SUCCESS:
- break; // We'll deal with that later
- case self::DELETE_PERM: // If we get PERM, BLOCKED or READONLY that's weird, but it's possible
- $this->dieUsage('You don\'t have permission to delete', 'permissiondenied');
- case self::DELETE_BLOCKED:
- $this->dieUsage('You have been blocked from editing', 'blocked');
- case self::DELETE_READONLY:
- $this->dieUsage('The wiki is in read-only mode', 'readonly');
- case self::DELETE_BADTOKEN:
- $this->dieUsage('Invalid token', 'badtoken');
- case self::DELETE_BADARTICLE:
- $this->dieUsage("The article ``{$params['title']}'' doesn't exist or has already been deleted", 'missingtitle');
- default:
- // delete() has apparently invented a new error, which is extremely weird
- $this->dieDebug(__METHOD__, "delete() returned an unknown error ($retval)");
- }
- // $retval has to be self::DELETE_SUCCESS if we get here
- $dbw->commit();
- $r = array('title' => $titleObj->getPrefixedText(), 'reason' => $reason);
- $this->getResult()->addValue(null, $this->getModuleName(), $r);
- }
-
- protected function getAllowedParams() {
- return array (
- 'title' => null,
- 'token' => null,
- 'reason' => null,
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'title' => 'Title of the page you want to delete.',
- 'token' => 'A delete token previously retrieved through prop=info',
- 'reason' => 'Reason for the deletion. If not set, an automatically generated reason will be used.'
- );
- }
-
- protected function getDescription() {
- return array(
- 'Deletes a page. You need to be logged in as a sysop to use this function, see also action=login.'
- );
- }
-
- protected function getExamples() {
- return array (
- 'api.php?action=delete&title=Main%20Page&token=123ABC',
- 'api.php?action=delete&title=Main%20Page&token=123ABC&reason=Preparing%20for%20move'
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiDelete.php 28209 2007-12-06 16:06:22Z vasilievvv $';
- }
-}
+++ /dev/null
-<?php
-
-/*
- * Created on Oct 31, 2007
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
-}
-
-
-/**
- * @addtogroup API
- */
-class ApiMove extends ApiBase {
-
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
- }
-
- public function execute() {
- global $wgUser;
- $this->getMain()->requestWriteMode();
- $params = $this->extractRequestParams();
- if(is_null($params['reason']))
- $params['reason'] = '';
-
- $titleObj = NULL;
- if(!isset($params['from']))
- $this->dieUsage('The from parameter must be set', 'nofrom');
- if(!isset($params['to']))
- $this->dieUsage('The to parameter must be set', 'noto');
- if(!isset($params['token']))
- $this->dieUsage('The token parameter must be set', 'notoken');
- if(!$wgUser->matchEditToken($params['token']))
- $this->dieUsage('Invalid token', 'badtoken');
-
- if($wgUser->isBlocked())
- $this->dieUsage('You have been blocked from editing', 'blocked');
- if(wfReadOnly())
- $this->dieUsage('The wiki is in read-only mode', 'readonly');
- if($params['noredirect'] && !$wgUser->isAllowed('suppressredirect'))
- $this->dieUsage("You don't have permission to suppress redirect creation", 'nosuppress');
-
- $fromTitle = Title::newFromText($params['from']);
- if(!$fromTitle)
- $this->dieUsage("Bad title ``{$params['from']}''", 'invalidtitle');
- if(!$fromTitle->exists())
- $this->dieUsage("``{$params['from']}'' doesn't exist", 'missingtitle');
- $fromTalk = $fromTitle->getTalkPage();
-
-
- $toTitle = Title::newFromText($params['to']);
- if(!$toTitle)
- $this->dieUsage("Bad title ``{$params['to']}''", 'invalidtitle');
- $toTalk = $toTitle->getTalkPage();
-
- $dbw = wfGetDB(DB_MASTER);
- $dbw->begin();
- $retval = $fromTitle->moveTo($toTitle, true, $params['reason'], !$params['noredirect']);
- if($retval !== true)
- switch($retval)
- {
- // case 'badtitletext': Can't happen
- // case 'badarticleerror': Can't happen
- case 'selfmove':
- $this->dieUsage("Can't move ``{$params['from']}'' to itself", 'selfmove');
- case 'immobile_namespace':
- if($fromTitle->isMovable())
- $this->dieUsage("Pages in the ``{$fromTitle->getNsText()}'' namespace can't be moved", 'immobilenamespace-from');
- $this->dieUsage("Pages in the ``{$toTitle->getNsText()}'' namespace can't be moved", 'immobilenamespace-to');
- case 'articleexists':
- $this->dieUsage("``{$toTitle->getPrefixedText()}'' already exists and is not a redirect to ``{$fromTitle->getPrefixedText()}''", 'targetexists');
- case 'protectedpage':
- $this->dieUsage("You don't have permission to move ``{$fromTitle->getPrefixedText()}'' to ``{$toTitle->getPrefixedText()}''", 'permissiondenied');
- default:
- throw new MWException( "Title::moveTo: Unknown return value ``{$retval}''" );
- }
- $r = array('from' => $fromTitle->getPrefixedText(), 'to' => $toTitle->getPrefixedText(), 'reason' => $params['reason']);
- if(!$params['noredirect'])
- $r['redirectcreated'] = '';
-
- if($params['movetalk'] && $fromTalk->exists() && !$fromTitle->isTalkPage())
- {
- // We need to move the talk page as well
- $toTalk = $toTitle->getTalkPage();
- $retval = $fromTalk->moveTo($toTalk, true, $params['reason'], !$params['noredirect']);
- if($retval === true)
- {
- $r['talkfrom'] = $fromTalk->getPrefixedText();
- $r['talkto'] = $toTalk->getPrefixedText();
- }
- // We're not gonna dieUsage() on failure, since we already changed something
- else
- switch($retval)
- {
- case 'immobile_namespace':
- if($fromTalk->isMovable())
- {
- $r['talkmove-error-code'] = 'immobilenamespace-from';
- $r['talkmove-error-info'] = "Pages in the ``{$fromTalk->getNsText()}'' namespace can't be moved";
- }
- else
- {
- $r['talkmove-error-code'] = 'immobilenamespace-to';
- $r['talkmove-error-info'] = "Pages in the ``{$toTalk->getNsText()}'' namespace can't be moved";
- }
- break;
- case 'articleexists':
- $r['talkmove-error-code'] = 'targetexists';
- $r['talkmove-error-info'] = "``{$toTalk->getPrefixedText()}'' already exists and is not a redirect to ``{$fromTalk->getPrefixedText()}''";
- break;
- case 'protectedpage':
- $r['talkmove-error-code'] = 'permissiondenied';
- $r['talkmove-error-info'] = "You don't have permission to move ``{$fromTalk->getPrefixedText()}'' to ``{$toTalk->getPrefixedText()}''";
- default:
- $r['talkmove-error-code'] = 'unknownerror';
- $r['talkmove-error-info'] = "Unknown error ``$retval''";
- }
- }
- $dbw->commit(); // Make sure all changes are really written to the DB
- $this->getResult()->addValue(null, $this->getModuleName(), $r);
- }
-
- protected function getAllowedParams() {
- return array (
- 'from' => null,
- 'to' => null,
- 'token' => null,
- 'reason' => null,
- 'movetalk' => false,
- 'noredirect' => false
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'from' => 'Title of the page you want to move.',
- 'to' => 'Title you want to rename the page to.',
- 'token' => 'A move token previously retrieved through prop=info',
- 'reason' => 'Reason for the move (optional).',
- 'movetalk' => 'Move the talk page, if it exists.',
- 'noredirect' => 'Don\'t create a redirect'
- );
- }
-
- protected function getDescription() {
- return array(
- 'Moves a page.'
- );
- }
-
- protected function getExamples() {
- return array (
- 'api.php?action=move&from=Exampel&to=Example&token=123ABC&reason=Misspelled%20title&movetalk&noredirect'
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiMove.php 28209 2007-12-06 16:06:22Z vasilievvv $';
- }
-}
+++ /dev/null
-<?php
-
-/*
- * Created on Sep 1, 2007
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
-}
-
-/**
- * @addtogroup API
- */
-class ApiProtect extends ApiBase {
-
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
- }
-
- public function execute() {
- global $wgUser;
- $this->getMain()->requestWriteMode();
- $params = $this->extractRequestParams();
-
- $titleObj = NULL;
- if(!isset($params['title']))
- $this->dieUsage('The title parameter must be set', 'notitle');
- if(!isset($params['token']))
- $this->dieUsage('The token parameter must be set', 'notoken');
- if(!isset($params['protections']) || empty($params['protections']))
- $this->dieUsage('The protections parameter must be set', 'noprotections');
-
- if($wgUser->isBlocked())
- $this->dieUsage('You have been blocked from editing', 'blocked');
- if(wfReadOnly())
- $this->dieUsage('The wiki is in read-only mode', 'readonly');
- if(!$wgUser->matchEditToken($params['token']))
- $this->dieUsage('Invalid token', 'badtoken');
-
- $titleObj = Title::newFromText($params['title']);
- if(!$titleObj)
- $this->dieUsage("Bad title ``{$params['title']}''", 'invalidtitle');
- if(!$titleObj->exists())
- $this->dieUsage("``{$params['title']}'' doesn't exist", 'missingtitle');
- if(!$titleObj->userCan('protect'))
- $this->dieUsage('You don\'t have permission to change protection levels', 'permissiondenied');
- $articleObj = new Article($titleObj);
-
- if(in_array($params['expiry'], array('infinite', 'indefinite', 'never')))
- $expiry = Block::infinity();
- else
- {
- $expiry = strtotime($params['expiry']);
- if($expiry < 0 || $expiry == false)
- $this->dieUsage('Invalid expiry time', 'invalidexpiry');
-
- $expiry = wfTimestamp(TS_MW, $expiry);
- if($expiry < wfTimestampNow())
- $this->dieUsage('Expiry time is in the past', 'pastexpiry');
- }
-
- $protections = array();
- foreach($params['protections'] as $prot)
- {
- $p = explode('=', $prot);
- $protections[$p[0]] = ($p[1] == 'all' ? '' : $p[1]);
- }
-
- $dbw = wfGetDb(DB_MASTER);
- $dbw->begin();
- $ok = $articleObj->updateRestrictions($protections, $params['reason'], $params['cascade'], $expiry);
- if(!$ok)
- // This is very weird. Maybe the article was deleted or the user was blocked/desysopped in the meantime?
- $this->dieUsage('Unknown error', 'unknownerror');
- $dbw->commit();
- $res = array('title' => $titleObj->getPrefixedText(), 'reason' => $params['reason'], 'expiry' => $expiry);
- if($params['cascade'])
- $res['cascade'] = '';
- $res['protections'] = $protections;
- $this->getResult()->addValue(null, $this->getModuleName(), $res);
- }
-
- protected function getAllowedParams() {
- return array (
- 'title' => null,
- 'token' => null,
- 'protections' => array(
- ApiBase :: PARAM_ISMULTI => true
- ),
- 'expiry' => 'infinite',
- 'reason' => '',
- 'cascade' => false
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'title' => 'Title of the page you want to restore.',
- 'token' => 'A protect token previously retrieved through prop=info',
- 'protections' => 'Pipe-separated list of protection levels, formatted action=group (e.g. edit=sysop)',
- 'expiry' => 'Expiry timestamp. If set to \'infinite\', \'indefinite\' or \'never\', the protection will never expire.',
- 'reason' => 'Reason for (un)protecting (optional)',
- 'cascade' => 'Enable cascading protection (i.e. protect pages included in this page)'
- );
- }
-
- protected function getDescription() {
- return array(
- 'Change the protection level of a page.'
- );
- }
-
- protected function getExamples() {
- return array (
- 'api.php?action=protect&title=Main%20Page&token=123ABC&protections=edit=sysop|move=sysop&cascade&expiry=20070901163000',
- 'api.php?action=protect&title=Main%20Page&token=123ABC&protections=edit=all|move=all&reason=Lifting%20restrictions'
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiProtect.php 28209 2007-12-06 16:06:22Z vasilievvv $';
- }
-}
+++ /dev/null
-<?php
-
-/*
- * Created on Jun 20, 2007
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
-}
-
-/**
- * @addtogroup API
- */
-class ApiRollback extends ApiBase {
-
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
- }
-
- public function execute() {
- global $wgUser;
- $this->getMain()->requestWriteMode();
- $params = $this->extractRequestParams();
-
- $titleObj = NULL;
- if(!isset($params['title']))
- $this->dieUsage('The title parameter must be set', 'notitle');
- if(!isset($params['user']))
- $this->dieUsage('The user parameter must be set', 'nouser');
- if(!isset($params['token']))
- $this->dieUsage('The token parameter must be set', 'notoken');
-
- // doRollback() also checks for these, but we wanna save some work
- if($wgUser->isBlocked())
- $this->dieUsage('You have been blocked from editing', 'blocked');
- if(wfReadOnly())
- $this->dieUsage('The wiki is in read-only mode', 'readonly');
-
- $titleObj = Title::newFromText($params['title']);
- if(!$titleObj)
- $this->dieUsage("Bad title ``{$params['title']}''", 'invalidtitle');
- if(!$titleObj->userCan('rollback'))
- $this->dieUsage('You don\'t have permission to rollback', 'permissiondenied');
-
- $username = User::getCanonicalName($params['user']);
- if(!$username)
- $this->dieUsage("Invalid username ``{$params['user']}''", 'invaliduser');
-
- $articleObj = new Article($titleObj);
- $summary = (isset($params['summary']) ? $params['summary'] : "");
- $details = NULL;
- $dbw = wfGetDb(DB_MASTER);
- $dbw->begin();
- $retval = $articleObj->doRollback($username, $summary, $params['token'], $params['markbot'], &$details);
-
- switch($retval)
- {
- case Article::SUCCESS:
- break; // We'll deal with that later
- case Article::PERM_DENIED:
- $this->dieUsage("You don't have permission to rollback", 'permissiondenied');
- case Article::BLOCKED: // If we get BLOCKED or PERM_DENIED that's very weird, but it's possible
- $this->dieUsage('You have been blocked from editing', 'blocked');
- case Article::READONLY:
- $this->dieUsage('The wiki is in read-only mode', 'readonly');
- case Article::BAD_TOKEN:
- $this->dieUsage('Invalid token', 'badtoken');
- case Article::BAD_TITLE:
- $this->dieUsage("``{$params['title']}'' doesn't exist", 'missingtitle');
- case Article::ALREADYROLLED:
- $current = $details['current'];
- $currentID = $current->getId();
- $this->dieUsage("The edit(s) you tried to rollback is/are already rolled back." .
- "The current revision ID is ``$currentID''", 'alreadyrolled');
- case Article::ONLY_AUTHOR:
- $this->dieUsage("User ``$username'' is the only author of the page", 'onlyauthor');
- case Article::RATE_LIMITED:
- $this->dieUsage("You can't rollback too many articles in too short a time. Please wait a little while and try again", 'ratelimited');
- default:
- // rollback() has apparently invented a new error, which is extremely weird
- $this->dieDebug(__METHOD__, "rollback() returned an unknown error ($retval)");
- }
- // $retval has to be Article::SUCCESS if we get here
- $dbw->commit();
- $current = $target = $summary = NULL;
- extract($details);
-
- $info = array(
- 'title' => $titleObj->getPrefixedText(),
- 'pageid' => $current->getPage(),
- 'summary' => $summary,
- 'revid' => $titleObj->getLatestRevID(),
- 'old_revid' => $current->getID(),
- 'last_revid' => $target->getID()
- );
-
- $this->getResult()->addValue(null, $this->getModuleName(), $info);
- }
-
- protected function getAllowedParams() {
- return array (
- 'title' => null,
- 'user' => null,
- 'token' => null,
- 'summary' => null,
- 'markbot' => false
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'title' => 'Title of the page you want to rollback.',
- 'user' => 'Name of the user whose edits are to be rolled back. If set incorrectly, you\'ll get a badtoken error.',
- 'token' => 'A rollback token previously retrieved through prop=info',
- 'summary' => 'Custom edit summary. If not set, default summary will be used.',
- 'markbot' => 'Mark the reverted edits and the revert as bot edits'
- );
- }
-
- protected function getDescription() {
- return array(
- 'Undoes the last edit to the page. If the last user who edited the page made multiple edits in a row,',
- 'they will all be rolled back. You need to be logged in as a sysop to use this function, see also action=login.'
- );
- }
-
- protected function getExamples() {
- return array (
- 'api.php?action=rollback&title=Main%20Page&user=Catrope&token=123ABC',
- 'api.php?action=rollback&title=Main%20Page&user=217.121.114.116&token=123ABC&summary=Reverting%20vandalism&markbot=1'
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiRollback.php 28209 2007-12-06 16:06:22Z vasilievvv $';
- }
-}
+++ /dev/null
-<?php
-
-/*
- * Created on Sep 7, 2007
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
-}
-
-/**
- * @addtogroup API
- */
-class ApiUnblock extends ApiBase {
-
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
- }
-
- public function execute() {
- global $wgUser;
- $this->getMain()->requestWriteMode();
- $params = $this->extractRequestParams();
-
- if($params['gettoken'])
- {
- $res['unblocktoken'] = $wgUser->editToken();
- $this->getResult()->addValue(null, $this->getModuleName(), $res);
- return;
- }
-
- if(is_null($params['id']) && is_null($params['user']))
- $this->dieUsage('Either the id or the user parameter must be set', 'notarget');
- if(!is_null($params['id']) && !is_null($params['user']))
- $this->dieUsage('The id and user parameters can\'t be used together', 'idanduser');
- if(is_null($params['token']))
- $this->dieUsage('The token parameter must be set', 'notoken');
- if(!$wgUser->matchEditToken($params['token']))
- $this->dieUsage('Invalid token', 'badtoken');
- if(!$wgUser->isAllowed('block'))
- $this->dieUsage('You don\'t have permission to unblock users', 'permissiondenied');
- if(wfReadOnly())
- $this->dieUsage('The wiki is in read-only mode', 'readonly');
-
- $id = $params['id'];
- $user = $params['user'];
- $reason = $params['reason'];
- $dbw = wfGetDb(DB_MASTER);
- $dbw->begin();
- $retval = IPUnblockForm::doUnblock(&$id, &$user, &$reason, &$range);
-
- switch($retval)
- {
- case IPUnblockForm::UNBLOCK_SUCCESS:
- break; // We'll deal with that later
- case IPUnblockForm::UNBLOCK_NO_SUCH_ID:
- $this->dieUsage("There is no block with ID ``$id''", 'nosuchid');
- case IPUnblockForm::UNBLOCK_USER_NOT_BLOCKED:
- $this->dieUsage("User ``$user'' is not blocked", 'notblocked');
- case IPUnblockForm::UNBLOCK_BLOCKED_AS_RANGE:
- $this->dieUsage("IP address ``$user'' was blocked as part of range ``$range''. You can't unblock the IP invidually, but you can unblock the range as a whole.", 'blockedasrange');
- case IPUnblockForm::UNBLOCK_UNKNOWNERR:
- $this->dieUsage("Unknown error", 'unknownerr');
- default:
- $this->dieDebug(__METHOD__, "IPBlockForm::doBlock() returned an unknown error ($retval)");
- }
- $dbw->commit();
-
- $res['id'] = $id;
- $res['user'] = $user;
- $res['reason'] = $reason;
- $this->getResult()->addValue(null, $this->getModuleName(), $res);
- }
-
- protected function getAllowedParams() {
- return array (
- 'id' => null,
- 'user' => null,
- 'token' => null,
- 'gettoken' => false,
- 'reason' => null,
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'id' => 'ID of the block you want to unblock (obtained through list=blocks). Cannot be user together with user',
- 'user' => 'Username, IP address or IP range you want to unblock. Cannot be used together with id',
- 'token' => 'An unblock token previously obtained through the gettoken parameter',
- 'gettoken' => 'If set, an unblock token will be returned, and no other action will be taken',
- 'reason' => 'Reason for unblock (optional)',
- );
- }
-
- protected function getDescription() {
- return array(
- 'Unblock a user.'
- );
- }
-
- protected function getExamples() {
- return array (
- 'api.php?action=unblock&id=105',
- 'api.php?action=unblock&user=Bob&reason=Sorry%20Bob'
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiUnblock.php 28209 2007-12-06 16:06:22Z vasilievvv $';
- }
-}
+++ /dev/null
-<?php
-
-/*
- * Created on Jul 3, 2007
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ("ApiBase.php");
-}
-
-/**
- * @addtogroup API
- */
-class ApiUndelete extends ApiBase {
-
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
- }
-
- public function execute() {
- global $wgUser;
- $this->getMain()->requestWriteMode();
- $params = $this->extractRequestParams();
-
- $titleObj = NULL;
- if(!isset($params['title']))
- $this->dieUsage('The title parameter must be set', 'notitle');
- if(!isset($params['token']))
- $this->dieUsage('The token parameter must be set', 'notoken');
-
- if(!$wgUser->isAllowed('undelete'))
- $this->dieUsage('You don\'t have permission to restore deleted revisions', 'permissiondenied');
- if($wgUser->isBlocked())
- $this->dieUsage('You have been blocked from editing', 'blocked');
- if(wfReadOnly())
- $this->dieUsage('The wiki is in read-only mode', 'readonly');
- if(!$wgUser->matchEditToken($params['token']))
- $this->dieUsage('Invalid token', 'badtoken');
-
- $titleObj = Title::newFromText($params['title']);
- if(!$titleObj)
- $this->dieUsage("Bad title ``{$params['title']}''", 'invalidtitle');
-
- // Convert timestamps
- if(!is_array($params['timestamps']))
- $params['timestamps'] = array($params['timestamps']);
- foreach($params['timestamps'] as $i => $ts)
- $params['timestamps'][$i] = wfTimestamp(TS_MW, $ts);
-
- $pa = new PageArchive($titleObj);
- $dbw = wfGetDb(DB_MASTER);
- $dbw->begin();
- $retval = $pa->undelete((isset($params['timestamps']) ? $params['timestamps'] : array()), $params['reason']);
- if(!is_array($retval))
- switch($retval)
- {
- case PageArchive::UNDELETE_NOTHINGRESTORED:
- $this->dieUsage('No revisions could be restored', 'norevs');
- case PageArchive::UNDELETE_NOTAVAIL:
- $this->dieUsage('Not all requested revisions could be found', 'revsnotfound');
- case PageArchive::UNDELETE_UNKNOWNERR:
- $this->dieUsage('Undeletion failed with unknown error', 'unknownerror');
- }
- $dbw->commit();
-
- $info['title'] = $titleObj->getPrefixedText();
- $info['revisions'] = $retval[0];
- $info['fileversions'] = $retval[1];
- $info['reason'] = $retval[2];
- $this->getResult()->addValue(null, $this->getModuleName(), $info);
- }
-
- protected function getAllowedParams() {
- return array (
- 'title' => null,
- 'token' => null,
- 'reason' => "",
- 'timestamps' => array(
- ApiBase :: PARAM_ISMULTI => true
- )
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'title' => 'Title of the page you want to restore.',
- 'token' => 'An undelete token previously retrieved through list=deletedrevs',
- 'reason' => 'Reason for restoring (optional)',
- 'timestamps' => 'Timestamps of the revisions to restore. If not set, all revisions will be restored.'
- );
- }
-
- protected function getDescription() {
- return array(
- 'Restore certain revisions of a deleted page. A list of deleted revisions (including timestamps) can be',
- 'retrieved through list=deletedrevs'
- );
- }
-
- protected function getExamples() {
- return array (
- 'api.php?action=undelete&title=Main%20Page&token=123ABC&reason=Restoring%20main%20page',
- 'api.php?action=undelete&title=Main%20Page&token=123ABC×tamps=20070703220045|20070702194856'
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiUndelete.php 28209 2007-12-06 16:06:22Z vasilievvv $';
- }
-}
+++ /dev/null
-<?php
-
-/*
- * Created on Sep 7, 2006
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ('ApiBase.php');
-}
-
-/**
- * This is the main query class. It behaves similar to ApiMain: based on the parameters given,
- * it will create a list of titles to work on (an instance of the ApiPageSet object)
- * instantiate and execute various property/list/meta modules,
- * and assemble all resulting data into a single ApiResult object.
- *
- * In the generator mode, a generator will be first executed to populate a second ApiPageSet object,
- * and that object will be used for all subsequent modules.
- *
- * @addtogroup API
- */
-class ApiQuery extends ApiBase {
-
- private $mPropModuleNames, $mListModuleNames, $mMetaModuleNames;
- private $mPageSet;
- private $params, $redirect;
-
- private $mQueryPropModules = array (
- 'info' => 'ApiQueryInfo',
- 'revisions' => 'ApiQueryRevisions',
- 'links' => 'ApiQueryLinks',
- 'langlinks' => 'ApiQueryLangLinks',
- 'images' => 'ApiQueryImages',
- 'imageinfo' => 'ApiQueryImageInfo',
- 'templates' => 'ApiQueryLinks',
- 'categories' => 'ApiQueryCategories',
- 'extlinks' => 'ApiQueryExternalLinks',
- );
-
- private $mQueryListModules = array (
- 'allpages' => 'ApiQueryAllpages',
- 'alllinks' => 'ApiQueryAllLinks',
- 'allusers' => 'ApiQueryAllUsers',
- 'backlinks' => 'ApiQueryBacklinks',
- 'blocks' => 'ApiQueryBlocks',
- 'categorymembers' => 'ApiQueryCategoryMembers',
- 'deletedrevs' => 'ApiQueryDeletedrevs',
- 'embeddedin' => 'ApiQueryBacklinks',
- 'imageusage' => 'ApiQueryBacklinks',
- 'logevents' => 'ApiQueryLogEvents',
- 'recentchanges' => 'ApiQueryRecentChanges',
- 'search' => 'ApiQuerySearch',
- 'usercontribs' => 'ApiQueryContributions',
- 'watchlist' => 'ApiQueryWatchlist',
- 'exturlusage' => 'ApiQueryExtLinksUsage',
- );
-
- private $mQueryMetaModules = array (
- 'siteinfo' => 'ApiQuerySiteinfo',
- 'userinfo' => 'ApiQueryUserInfo',
- 'allmessages' => 'ApiQueryAllmessages',
- );
-
- private $mSlaveDB = null;
- private $mNamedDB = array();
-
- public function __construct($main, $action) {
- parent :: __construct($main, $action);
-
- // Allow custom modules to be added in LocalSettings.php
- global $wgApiQueryPropModules, $wgApiQueryListModules, $wgApiQueryMetaModules;
- self :: appendUserModules($this->mQueryPropModules, $wgApiQueryPropModules);
- self :: appendUserModules($this->mQueryListModules, $wgApiQueryListModules);
- self :: appendUserModules($this->mQueryMetaModules, $wgApiQueryMetaModules);
-
- $this->mPropModuleNames = array_keys($this->mQueryPropModules);
- $this->mListModuleNames = array_keys($this->mQueryListModules);
- $this->mMetaModuleNames = array_keys($this->mQueryMetaModules);
-
- // Allow the entire list of modules at first,
- // but during module instantiation check if it can be used as a generator.
- $this->mAllowedGenerators = array_merge($this->mListModuleNames, $this->mPropModuleNames);
- }
-
- /**
- * Helper function to append any add-in modules to the list
- */
- private static function appendUserModules(&$modules, $newModules) {
- if (is_array( $newModules )) {
- foreach ( $newModules as $moduleName => $moduleClass) {
- $modules[$moduleName] = $moduleClass;
- }
- }
- }
-
- /**
- * Gets a default slave database connection object
- */
- public function getDB() {
- if (!isset ($this->mSlaveDB)) {
- $this->profileDBIn();
- $this->mSlaveDB = wfGetDB(DB_SLAVE);
- $this->profileDBOut();
- }
- return $this->mSlaveDB;
- }
-
- /**
- * Get the query database connection with the given name.
- * If no such connection has been requested before, it will be created.
- * Subsequent calls with the same $name will return the same connection
- * as the first, regardless of $db or $groups new values.
- */
- public function getNamedDB($name, $db, $groups) {
- if (!array_key_exists($name, $this->mNamedDB)) {
- $this->profileDBIn();
- $this->mNamedDB[$name] = wfGetDB($db, $groups);
- $this->profileDBOut();
- }
- return $this->mNamedDB[$name];
- }
-
- /**
- * Gets the set of pages the user has requested (or generated)
- */
- public function getPageSet() {
- return $this->mPageSet;
- }
-
- /**
- * Query execution happens in the following steps:
- * #1 Create a PageSet object with any pages requested by the user
- * #2 If using generator, execute it to get a new PageSet object
- * #3 Instantiate all requested modules.
- * This way the PageSet object will know what shared data is required,
- * and minimize DB calls.
- * #4 Output all normalization and redirect resolution information
- * #5 Execute all requested modules
- */
- public function execute() {
-
- $this->params = $this->extractRequestParams();
- $this->redirects = $this->params['redirects'];
-
- //
- // Create PageSet
- //
- $this->mPageSet = new ApiPageSet($this, $this->redirects);
-
- //
- // Instantiate requested modules
- //
- $modules = array ();
- $this->InstantiateModules($modules, 'prop', $this->mQueryPropModules);
- $this->InstantiateModules($modules, 'list', $this->mQueryListModules);
- $this->InstantiateModules($modules, 'meta', $this->mQueryMetaModules);
-
- //
- // If given, execute generator to substitute user supplied data with generated data.
- //
- if (isset ($this->params['generator'])) {
- $this->executeGeneratorModule($this->params['generator'], $modules);
- } else {
- // Append custom fields and populate page/revision information
- $this->addCustomFldsToPageSet($modules, $this->mPageSet);
- $this->mPageSet->execute();
- }
-
- //
- // Record page information (title, namespace, if exists, etc)
- //
- $this->outputGeneralPageInfo();
-
- //
- // Execute all requested modules.
- //
- foreach ($modules as $module) {
- $module->profileIn();
- $module->execute();
- $module->profileOut();
- }
- }
-
- /**
- * Query modules may optimize data requests through the $this->getPageSet() object
- * by adding extra fields from the page table.
- * This function will gather all the extra request fields from the modules.
- */
- private function addCustomFldsToPageSet($modules, $pageSet) {
- // Query all requested modules.
- foreach ($modules as $module) {
- $module->requestExtraData($pageSet);
- }
- }
-
- /**
- * Create instances of all modules requested by the client
- */
- private function InstantiateModules(&$modules, $param, $moduleList) {
- $list = $this->params[$param];
- if (isset ($list))
- foreach ($list as $moduleName)
- $modules[] = new $moduleList[$moduleName] ($this, $moduleName);
- }
-
- /**
- * Appends an element for each page in the current pageSet with the most general
- * information (id, title), plus any title normalizations and missing title/pageids/revids.
- */
- private function outputGeneralPageInfo() {
-
- $pageSet = $this->getPageSet();
- $result = $this->getResult();
-
- // Title normalizations
- $normValues = array ();
- foreach ($pageSet->getNormalizedTitles() as $rawTitleStr => $titleStr) {
- $normValues[] = array (
- 'from' => $rawTitleStr,
- 'to' => $titleStr
- );
- }
-
- if (!empty ($normValues)) {
- $result->setIndexedTagName($normValues, 'n');
- $result->addValue('query', 'normalized', $normValues);
- }
-
- // Interwiki titles
- $intrwValues = array ();
- foreach ($pageSet->getInterwikiTitles() as $rawTitleStr => $interwikiStr) {
- $intrwValues[] = array (
- 'title' => $rawTitleStr,
- 'iw' => $interwikiStr
- );
- }
-
- if (!empty ($intrwValues)) {
- $result->setIndexedTagName($intrwValues, 'i');
- $result->addValue('query', 'interwiki', $intrwValues);
- }
-
- // Show redirect information
- $redirValues = array ();
- foreach ($pageSet->getRedirectTitles() as $titleStrFrom => $titleStrTo) {
- $redirValues[] = array (
- 'from' => $titleStrFrom,
- 'to' => $titleStrTo
- );
- }
-
- if (!empty ($redirValues)) {
- $result->setIndexedTagName($redirValues, 'r');
- $result->addValue('query', 'redirects', $redirValues);
- }
-
- //
- // Missing revision elements
- //
- $missingRevIDs = $pageSet->getMissingRevisionIDs();
- if (!empty ($missingRevIDs)) {
- $revids = array ();
- foreach ($missingRevIDs as $revid) {
- $revids[$revid] = array (
- 'revid' => $revid
- );
- }
- $result->setIndexedTagName($revids, 'rev');
- $result->addValue('query', 'badrevids', $revids);
- }
-
- //
- // Page elements
- //
- $pages = array ();
-
- // Report any missing titles
- foreach ($pageSet->getMissingTitles() as $fakeId => $title) {
- $vals = array();
- ApiQueryBase :: addTitleInfo($vals, $title);
- $vals['missing'] = '';
- $pages[$fakeId] = $vals;
- }
-
- // Report any missing page ids
- foreach ($pageSet->getMissingPageIDs() as $pageid) {
- $pages[$pageid] = array (
- 'pageid' => $pageid,
- 'missing' => ''
- );
- }
-
- // Output general page information for found titles
- foreach ($pageSet->getGoodTitles() as $pageid => $title) {
- $vals = array();
- $vals['pageid'] = $pageid;
- ApiQueryBase :: addTitleInfo($vals, $title);
- $pages[$pageid] = $vals;
- }
-
- if (!empty ($pages)) {
-
- if ($this->params['indexpageids']) {
- $pageIDs = array_keys($pages);
- // json treats all map keys as strings - converting to match
- $pageIDs = array_map('strval', $pageIDs);
- $result->setIndexedTagName($pageIDs, 'id');
- $result->addValue('query', 'pageids', $pageIDs);
- }
-
- $result->setIndexedTagName($pages, 'page');
- $result->addValue('query', 'pages', $pages);
- }
- }
-
- /**
- * For generator mode, execute generator, and use its output as new pageSet
- */
- protected function executeGeneratorModule($generatorName, $modules) {
-
- // Find class that implements requested generator
- if (isset ($this->mQueryListModules[$generatorName])) {
- $className = $this->mQueryListModules[$generatorName];
- } elseif (isset ($this->mQueryPropModules[$generatorName])) {
- $className = $this->mQueryPropModules[$generatorName];
- } else {
- ApiBase :: dieDebug(__METHOD__, "Unknown generator=$generatorName");
- }
-
- // Generator results
- $resultPageSet = new ApiPageSet($this, $this->redirects);
-
- // Create and execute the generator
- $generator = new $className ($this, $generatorName);
- if (!$generator instanceof ApiQueryGeneratorBase)
- $this->dieUsage("Module $generatorName cannot be used as a generator", "badgenerator");
-
- $generator->setGeneratorMode();
-
- // Add any additional fields modules may need
- $generator->requestExtraData($this->mPageSet);
- $this->addCustomFldsToPageSet($modules, $resultPageSet);
-
- // Populate page information with the original user input
- $this->mPageSet->execute();
-
- // populate resultPageSet with the generator output
- $generator->profileIn();
- $generator->executeGenerator($resultPageSet);
- $resultPageSet->finishPageSetGeneration();
- $generator->profileOut();
-
- // Swap the resulting pageset back in
- $this->mPageSet = $resultPageSet;
- }
-
- /**
- * Returns the list of allowed parameters for this module.
- * Qurey module also lists all ApiPageSet parameters as its own.
- */
- protected function getAllowedParams() {
- return array (
- 'prop' => array (
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_TYPE => $this->mPropModuleNames
- ),
- 'list' => array (
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_TYPE => $this->mListModuleNames
- ),
- 'meta' => array (
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_TYPE => $this->mMetaModuleNames
- ),
- 'generator' => array (
- ApiBase :: PARAM_TYPE => $this->mAllowedGenerators
- ),
- 'redirects' => false,
- 'indexpageids' => false,
- );
- }
-
- /**
- * Override the parent to generate help messages for all available query modules.
- */
- public function makeHelpMsg() {
-
- $msg = '';
-
- // Make sure the internal object is empty
- // (just in case a sub-module decides to optimize during instantiation)
- $this->mPageSet = null;
- $this->mAllowedGenerators = array(); // Will be repopulated
-
- $astriks = str_repeat('--- ', 8);
- $msg .= "\n$astriks Query: Prop $astriks\n\n";
- $msg .= $this->makeHelpMsgHelper($this->mQueryPropModules, 'prop');
- $msg .= "\n$astriks Query: List $astriks\n\n";
- $msg .= $this->makeHelpMsgHelper($this->mQueryListModules, 'list');
- $msg .= "\n$astriks Query: Meta $astriks\n\n";
- $msg .= $this->makeHelpMsgHelper($this->mQueryMetaModules, 'meta');
-
- // Perform the base call last because the $this->mAllowedGenerators
- // will be updated inside makeHelpMsgHelper()
- // Use parent to make default message for the query module
- $msg = parent :: makeHelpMsg() . $msg;
-
- return $msg;
- }
-
- /**
- * For all modules in $moduleList, generate help messages and join them together
- */
- private function makeHelpMsgHelper($moduleList, $paramName) {
-
- $moduleDscriptions = array ();
-
- foreach ($moduleList as $moduleName => $moduleClass) {
- $module = new $moduleClass ($this, $moduleName, null);
-
- $msg = ApiMain::makeHelpMsgHeader($module, $paramName);
- $msg2 = $module->makeHelpMsg();
- if ($msg2 !== false)
- $msg .= $msg2;
- if ($module instanceof ApiQueryGeneratorBase) {
- $this->mAllowedGenerators[] = $moduleName;
- $msg .= "Generator:\n This module may be used as a generator\n";
- }
- $moduleDscriptions[] = $msg;
- }
-
- return implode("\n", $moduleDscriptions);
- }
-
- /**
- * Override to add extra parameters from PageSet
- */
- public function makeHelpMsgParameters() {
- $psModule = new ApiPageSet($this);
- return $psModule->makeHelpMsgParameters() . parent :: makeHelpMsgParameters();
- }
-
- // @todo should work correctly
- public function shouldCheckMaxlag() {
- return true;
- }
-
- protected function getParamDescription() {
- return array (
- 'prop' => 'Which properties to get for the titles/revisions/pageids',
- 'list' => 'Which lists to get',
- 'meta' => 'Which meta data to get about the site',
- 'generator' => 'Use the output of a list as the input for other prop/list/meta items',
- 'redirects' => 'Automatically resolve redirects',
- 'indexpageids' => 'Include an additional pageids section listing all returned page IDs.'
- );
- }
-
- protected function getDescription() {
- return array (
- 'Query API module allows applications to get needed pieces of data from the MediaWiki databases,',
- 'and is loosely based on the Query API interface currently available on all MediaWiki servers.',
- 'All data modifications will first have to use query to acquire a token to prevent abuse from malicious sites.'
- );
- }
-
- protected function getExamples() {
- return array (
- 'api.php?action=query&prop=revisions&meta=siteinfo&titles=Main%20Page&rvprop=user|comment'
- );
- }
-
- public function getVersion() {
- $psModule = new ApiPageSet($this);
- $vers = array ();
- $vers[] = __CLASS__ . ': $Id: ApiQuery.php 28051 2007-12-02 14:24:07Z catrope $';
- $vers[] = $psModule->getVersion();
- return $vers;
- }
-}
-
+++ /dev/null
-<?php
-
-/*
- * Created on July 7, 2007
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
-}
-
-/**
- * Query module to enumerate links from all pages together.
- *
- * @addtogroup API
- */
-class ApiQueryAllLinks extends ApiQueryGeneratorBase {
-
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'al');
- }
-
- public function execute() {
- $this->run();
- }
-
- public function executeGenerator($resultPageSet) {
- $this->run($resultPageSet);
- }
-
- private function run($resultPageSet = null) {
-
- $db = $this->getDB();
- $params = $this->extractRequestParams();
-
- $prop = array_flip($params['prop']);
- $fld_ids = isset($prop['ids']);
- $fld_title = isset($prop['title']);
-
- if ($params['unique']) {
- if (!is_null($resultPageSet))
- $this->dieUsage($this->getModuleName() . ' cannot be used as a generator in unique links mode', 'params');
- if ($fld_ids)
- $this->dieUsage($this->getModuleName() . ' cannot return corresponding page ids in unique links mode', 'params');
- $this->addOption('DISTINCT');
- }
-
- $this->addTables('pagelinks');
- $this->addWhereFld('pl_namespace', $params['namespace']);
-
- if (!is_null($params['from']))
- $this->addWhere('pl_title>=' . $db->addQuotes(ApiQueryBase :: titleToKey($params['from'])));
- if (isset ($params['prefix']))
- $this->addWhere("pl_title LIKE '" . $db->escapeLike(ApiQueryBase :: titleToKey($params['prefix'])) . "%'");
-
- if (is_null($resultPageSet)) {
- $this->addFields(array (
- 'pl_namespace',
- 'pl_title'
- ));
- $this->addFieldsIf('pl_from', $fld_ids);
- } else {
- $this->addFields('pl_from');
- $pageids = array();
- }
-
- $this->addOption('USE INDEX', 'pl_namespace');
- $limit = $params['limit'];
- $this->addOption('LIMIT', $limit+1);
- $this->addOption('ORDER BY', 'pl_namespace, pl_title');
-
- $res = $this->select(__METHOD__);
-
- $data = array ();
- $count = 0;
- while ($row = $db->fetchObject($res)) {
- if (++ $count > $limit) {
- // We've reached the one extra which shows that there are additional pages to be had. Stop here...
- // TODO: Security issue - if the user has no right to view next title, it will still be shown
- $this->setContinueEnumParameter('from', ApiQueryBase :: keyToTitle($row->pl_title));
- break;
- }
-
- if (is_null($resultPageSet)) {
- $vals = array();
- if ($fld_ids)
- $vals['fromid'] = intval($row->pl_from);
- if ($fld_title) {
- $title = Title :: makeTitle($row->pl_namespace, $row->pl_title);
- $vals['ns'] = intval($title->getNamespace());
- $vals['title'] = $title->getPrefixedText();
- }
- $data[] = $vals;
- } else {
- $pageids[] = $row->pl_from;
- }
- }
- $db->freeResult($res);
-
- if (is_null($resultPageSet)) {
- $result = $this->getResult();
- $result->setIndexedTagName($data, 'l');
- $result->addValue('query', $this->getModuleName(), $data);
- } else {
- $resultPageSet->populateFromPageIDs($pageids);
- }
- }
-
- protected function getAllowedParams() {
- return array (
- 'from' => null,
- 'prefix' => null,
- 'unique' => false,
- 'prop' => array (
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_DFLT => 'title',
- ApiBase :: PARAM_TYPE => array (
- 'ids',
- 'title'
- )
- ),
- 'namespace' => array (
- ApiBase :: PARAM_DFLT => 0,
- ApiBase :: PARAM_TYPE => 'namespace'
- ),
- 'limit' => array (
- ApiBase :: PARAM_DFLT => 10,
- ApiBase :: PARAM_TYPE => 'limit',
- ApiBase :: PARAM_MIN => 1,
- ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
- ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
- )
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'from' => 'The page title to start enumerating from.',
- 'prefix' => 'Search for all page titles that begin with this value.',
- 'unique' => 'Only show unique links. Cannot be used with generator or prop=ids',
- 'prop' => 'What pieces of information to include',
- 'namespace' => 'The namespace to enumerate.',
- 'limit' => 'How many total links to return.'
- );
- }
-
- protected function getDescription() {
- return 'Enumerate all links that point to a given namespace';
- }
-
- protected function getExamples() {
- return array (
- 'api.php?action=query&list=alllinks&alunique&alfrom=B',
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryAllLinks.php 24453 2007-07-30 08:09:15Z yurik $';
- }
-}
+++ /dev/null
-<?php
-
-/*
- * Created on July 7, 2007
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2007 Yuri Astrakhan <Firstname><Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
-}
-
-/**
- * Query module to enumerate all registered users.
- *
- * @addtogroup API
- */
-class ApiQueryAllUsers extends ApiQueryBase {
-
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'au');
- }
-
- public function execute() {
- $db = $this->getDB();
- $params = $this->extractRequestParams();
-
- $prop = $params['prop'];
- if (!is_null($prop)) {
- $prop = array_flip($prop);
- $fld_editcount = isset($prop['editcount']);
- $fld_groups = isset($prop['groups']);
- $fld_registration = isset($prop['registration']);
- } else {
- $fld_editcount = $fld_groups = $fld_registration = false;
- }
-
- $limit = $params['limit'];
- $tables = $db->tableName('user');
-
- if( !is_null( $params['from'] ) )
- $this->addWhere( 'user_name >= ' . $db->addQuotes( self::keyToTitle( $params['from'] ) ) );
-
- if( isset( $params['prefix'] ) )
- $this->addWhere( 'user_name LIKE "' . $db->escapeLike( self::keyToTitle( $params['prefix'] ) ) . '%"' );
-
- if (!is_null($params['group'])) {
- // Filter only users that belong to a given group
- $tblName = $db->tableName('user_groups');
- $tables = "$tables INNER JOIN $tblName ug1 ON ug1.ug_user=user_id";
- $this->addWhereFld('ug1.ug_group', $params['group']);
- }
-
- if ($fld_groups) {
- // Show the groups the given users belong to
- // request more than needed to avoid not getting all rows that belong to one user
- $groupCount = count(User::getAllGroups());
- $sqlLimit = $limit+$groupCount+1;
-
- $tblName = $db->tableName('user_groups');
- $tables = "$tables LEFT JOIN $tblName ug2 ON ug2.ug_user=user_id";
- $this->addFields('ug2.ug_group ug_group2');
- } else {
- $sqlLimit = $limit+1;
- }
-
- if ($fld_registration)
- $this->addFields('user_registration');
-
- $this->addOption('LIMIT', $sqlLimit);
- $this->addTables($tables);
-
- $this->addFields('user_name');
- $this->addFieldsIf('user_editcount', $fld_editcount);
-
- $this->addOption('ORDER BY', 'user_name');
-
- $res = $this->select(__METHOD__);
-
- $data = array ();
- $count = 0;
- $lastUserData = false;
- $lastUser = false;
- $result = $this->getResult();
-
- //
- // This loop keeps track of the last entry.
- // For each new row, if the new row is for different user then the last, the last entry is added to results.
- // Otherwise, the group of the new row is appended to the last entry.
- // The setContinue... is more complex because of this, and takes into account the higher sql limit
- // to make sure all rows that belong to the same user are received.
- //
- while (true) {
-
- $row = $db->fetchObject($res);
- $count++;
-
- if (!$row || $lastUser != $row->user_name) {
- // Save the last pass's user data
- if (is_array($lastUserData))
- $data[] = $lastUserData;
-
- // No more rows left
- if (!$row)
- break;
-
- if ($count > $limit) {
- // We've reached the one extra which shows that there are additional pages to be had. Stop here...
- $this->setContinueEnumParameter('from', ApiQueryBase :: keyToTitle($row->user_name));
- break;
- }
-
- // Record new user's data
- $lastUser = $row->user_name;
- $lastUserData = array( 'name' => $lastUser );
- if ($fld_editcount)
- $lastUserData['editcount'] = intval($row->user_editcount);
- if ($fld_registration)
- $lastUserData['registration'] = wfTimestamp(TS_ISO_8601, $row->user_registration);
-
- }
-
- if ($sqlLimit == $count) {
- // BUG! database contains group name that User::getAllGroups() does not return
- // TODO: should handle this more gracefully
- ApiBase :: dieDebug(__METHOD__,
- 'MediaWiki configuration error: the database contains more user groups than known to User::getAllGroups() function');
- }
-
- // Add user's group info
- if ($fld_groups && !is_null($row->ug_group2)) {
- $lastUserData['groups'][] = $row->ug_group2;
- $result->setIndexedTagName($lastUserData['groups'], 'g');
- }
- }
-
- $db->freeResult($res);
-
- $result->setIndexedTagName($data, 'u');
- $result->addValue('query', $this->getModuleName(), $data);
- }
-
- protected function getAllowedParams() {
- return array (
- 'from' => null,
- 'prefix' => null,
- 'group' => array(
- ApiBase :: PARAM_TYPE => User::getAllGroups()
- ),
- 'prop' => array (
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_TYPE => array (
- 'editcount',
- 'groups',
- 'registration',
- )
- ),
- 'limit' => array (
- ApiBase :: PARAM_DFLT => 10,
- ApiBase :: PARAM_TYPE => 'limit',
- ApiBase :: PARAM_MIN => 1,
- ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
- ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
- )
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'from' => 'The user name to start enumerating from.',
- 'prefix' => 'Search for all page titles that begin with this value.',
- 'group' => 'Limit users to a given group name',
- 'prop' => array(
- 'What pieces of information to include.',
- '`groups` property uses more server resources and may return fewer results than the limit.'),
- 'limit' => 'How many total user names to return.',
- );
- }
-
- protected function getDescription() {
- return 'Enumerate all registered users';
- }
-
- protected function getExamples() {
- return array (
- 'api.php?action=query&list=allusers&aufrom=Y',
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryAllUsers.php 26953 2007-10-26 03:48:58Z amidaniel $';
- }
-}
+++ /dev/null
-<?php
-
-/*
- * Created on Dec 1, 2007
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
-}
-
-/**
- * A query action to return messages from site message cache
- *
- * @addtogroup API
- */
-class ApiQueryAllmessages extends ApiQueryBase {
-
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'am');
- }
-
- public function execute() {
- global $wgMessageCache;
- $params = $this->extractRequestParams();
-
- //Determine which messages should we print
- $messages_target = array();
- if( $params['messages'] == '*' ) {
- $wgMessageCache->loadAllMessages();
- $message_names = array_keys( array_merge( Language::getMessagesFor( 'en' ), $wgMessageCache->getExtensionMessagesFor( 'en' ) ) );
- sort( $message_names );
- $messages_target = $message_names;
- } else {
- $messages_target = explode( '|', $params['messages'] );
- }
-
- //Filter messages
- if( isset( $params['filter'] ) ) {
- $messages_filtered = array();
- foreach( $messages_target as $message ) {
- if( strpos( $message, $params['filter'] ) !== false ) { //!== is used because filter can be at the beginnig of the string
- $messages_filtered[] = $message;
- }
- }
- $messages_target = $messages_filtered;
- }
-
- $wgMessageCache->disableTransform();
-
- //Get all requested messages
- $messages = array();
- foreach( $messages_target as $message ) {
- $message = trim( $message ); //Message list can be formatted like "msg1 | msg2 | msg3", so let's trim() it
- $messages[$message] = wfMsg( $message );
- }
-
- //Print the result
- $result = $this->getResult();
- $messages_out = array();
- foreach( $messages as $name => $value ) {
- $message = array();
- $message['name'] = $name;
- $result->setContent( $message, $value );
- $messages_out[] = $message;
- }
- $result->setIndexedTagName( $messages_out, 'message' );
- $result->addValue( null, $this->getModuleName(), $messages_out );
- }
-
- protected function getAllowedParams() {
- return array (
- 'messages' => array (
- ApiBase :: PARAM_DFLT => '*',
- ),
- 'filter' => array(),
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'messages' => 'Which messages to output. "*" means all messages',
- 'filter' => 'Return only messages that contains specified string',
- );
- }
-
- protected function getDescription() {
- return 'Return messages from this site.';
- }
-
- protected function getExamples() {
- return array(
- 'api.php?action=query&meta=allmessages&amfilter=ipb-',
- 'api.php?action=query&meta=allmessages&ammessages=august|mainpage',
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryAllmessages.php 28027 2007-12-01 17:04:13Z vasilievvv $';
- }
-}
+++ /dev/null
-<?php
-
-/*
- * Created on Sep 25, 2006
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
-}
-
-/**
- * Query module to enumerate all available pages.
- *
- * @addtogroup API
- */
-class ApiQueryAllpages extends ApiQueryGeneratorBase {
-
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'ap');
- }
-
- public function execute() {
- $this->run();
- }
-
- public function executeGenerator($resultPageSet) {
- if ($resultPageSet->isResolvingRedirects())
- $this->dieUsage('Use "gapfilterredir=nonredirects" option instead of "redirects" when using allpages as a generator', 'params');
-
- $this->run($resultPageSet);
- }
-
- private function run($resultPageSet = null) {
-
- $db = $this->getDB();
-
- $params = $this->extractRequestParams();
-
- // Page filters
- if (!$this->addWhereIf('page_is_redirect = 1', $params['filterredir'] === 'redirects'))
- $this->addWhereIf('page_is_redirect = 0', $params['filterredir'] === 'nonredirects');
- $this->addWhereFld('page_namespace', $params['namespace']);
- if (!is_null($params['from']))
- $this->addWhere('page_title>=' . $db->addQuotes(ApiQueryBase :: titleToKey($params['from'])));
- if (isset ($params['prefix']))
- $this->addWhere("page_title LIKE '" . $db->escapeLike(ApiQueryBase :: titleToKey($params['prefix'])) . "%'");
-
- $forceNameTitleIndex = true;
- if (isset ($params['minsize'])) {
- $this->addWhere('page_len>=' . intval($params['minsize']));
- $forceNameTitleIndex = false;
- }
-
- if (isset ($params['maxsize'])) {
- $this->addWhere('page_len<=' . intval($params['maxsize']));
- $forceNameTitleIndex = false;
- }
-
- // Page protection filtering
- if (isset ($params['prtype'])) {
- $this->addTables('page_restrictions');
- $this->addWhere('page_id=pr_page');
- $this->addWhere('pr_expiry>' . $db->addQuotes($db->timestamp()));
- $this->addWhereFld('pr_type', $params['prtype']);
-
- $prlevel = $params['prlevel'];
- if (!is_null($prlevel) && $prlevel != '' && $prlevel != '*')
- $this->addWhereFld('pr_level', $prlevel);
-
- $this->addOption('DISTINCT');
-
- $forceNameTitleIndex = false;
-
- } else if (isset ($params['prlevel'])) {
- $this->dieUsage('prlevel may not be used without prtype', 'params');
- }
-
- $this->addTables('page');
- if ($forceNameTitleIndex)
- $this->addOption('USE INDEX', 'name_title');
-
-
- if (is_null($resultPageSet)) {
- $this->addFields(array (
- 'page_id',
- 'page_namespace',
- 'page_title'
- ));
- } else {
- $this->addFields($resultPageSet->getPageTableFields());
- }
-
- $limit = $params['limit'];
- $this->addOption('LIMIT', $limit+1);
- $this->addOption('ORDER BY', 'page_namespace, page_title' .
- ($params['dir'] == 'ZtoA' ? ' DESC' : ''));
-
- $res = $this->select(__METHOD__);
-
- $data = array ();
- $count = 0;
- while ($row = $db->fetchObject($res)) {
- if (++ $count > $limit) {
- // We've reached the one extra which shows that there are additional pages to be had. Stop here...
- // TODO: Security issue - if the user has no right to view next title, it will still be shown
- $this->setContinueEnumParameter('from', ApiQueryBase :: keyToTitle($row->page_title));
- break;
- }
-
- if (is_null($resultPageSet)) {
- $title = Title :: makeTitle($row->page_namespace, $row->page_title);
- $data[] = array(
- 'pageid' => intval($row->page_id),
- 'ns' => intval($title->getNamespace()),
- 'title' => $title->getPrefixedText());
- } else {
- $resultPageSet->processDbRow($row);
- }
- }
- $db->freeResult($res);
-
- if (is_null($resultPageSet)) {
- $result = $this->getResult();
- $result->setIndexedTagName($data, 'p');
- $result->addValue('query', $this->getModuleName(), $data);
- }
- }
-
- protected function getAllowedParams() {
- global $wgRestrictionTypes, $wgRestrictionLevels;
-
- return array (
- 'from' => null,
- 'prefix' => null,
- 'namespace' => array (
- ApiBase :: PARAM_DFLT => 0,
- ApiBase :: PARAM_TYPE => 'namespace',
- ),
- 'filterredir' => array (
- ApiBase :: PARAM_DFLT => 'all',
- ApiBase :: PARAM_TYPE => array (
- 'all',
- 'redirects',
- 'nonredirects'
- )
- ),
- 'minsize' => array (
- ApiBase :: PARAM_TYPE => 'integer',
- ),
- 'maxsize' => array (
- ApiBase :: PARAM_TYPE => 'integer',
- ),
- 'prtype' => array (
- ApiBase :: PARAM_TYPE => $wgRestrictionTypes,
- ApiBase :: PARAM_ISMULTI => true
- ),
- 'prlevel' => array (
- ApiBase :: PARAM_TYPE => $wgRestrictionLevels,
- ApiBase :: PARAM_ISMULTI => true
- ),
- 'limit' => array (
- ApiBase :: PARAM_DFLT => 10,
- ApiBase :: PARAM_TYPE => 'limit',
- ApiBase :: PARAM_MIN => 1,
- ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
- ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
- ),
- 'dir' => array (
- ApiBase :: PARAM_DFLT => 'AtoZ',
- ApiBase :: PARAM_TYPE => array (
- 'AtoZ',
- 'ZtoA'
- )
- )
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'from' => 'The page title to start enumerating from.',
- 'prefix' => 'Search for all page titles that begin with this value.',
- 'namespace' => 'The namespace to enumerate.',
- 'filterredir' => 'Which pages to list.',
- 'dir' => 'The direction in which to list',
- 'minsize' => 'Limit to pages with at least this many bytes',
- 'maxsize' => 'Limit to pages with at most this many bytes',
- 'prtype' => 'Limit to protected pages only',
- 'prlevel' => 'The protection level (must be used with apprtype= parameter)',
- 'limit' => 'How many total pages to return.'
- );
- }
-
- protected function getDescription() {
- return 'Enumerate all pages sequentially in a given namespace';
- }
-
- protected function getExamples() {
- return array (
- 'Simple Use',
- ' Show a list of pages starting at the letter "B"',
- ' api.php?action=query&list=allpages&apfrom=B',
- 'Using as Generator',
- ' Show info about 4 pages starting at the letter "T"',
- ' api.php?action=query&generator=allpages&gaplimit=4&gapfrom=T&prop=info',
- ' Show content of first 2 non-redirect pages begining at "Re"',
- ' api.php?action=query&generator=allpages&gaplimit=2&gapfilterredir=nonredirects&gapfrom=Re&prop=revisions&rvprop=content'
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryAllpages.php 26725 2007-10-15 13:50:43Z catrope $';
- }
-}
-
+++ /dev/null
-<?php
-
-/*
- * Created on Oct 16, 2006
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ("ApiQueryBase.php");
-}
-
-/**
- * This is three-in-one module to query:
- * * backlinks - links pointing to the given page,
- * * embeddedin - what pages transclude the given page within themselves,
- * * imageusage - what pages use the given image
- *
- * @addtogroup API
- */
-class ApiQueryBacklinks extends ApiQueryGeneratorBase {
-
- private $params, $rootTitle, $contRedirs, $contLevel, $contTitle, $contID;
-
- // output element name, database column field prefix, database table
- private $backlinksSettings = array (
- 'backlinks' => array (
- 'code' => 'bl',
- 'prefix' => 'pl',
- 'linktbl' => 'pagelinks'
- ),
- 'embeddedin' => array (
- 'code' => 'ei',
- 'prefix' => 'tl',
- 'linktbl' => 'templatelinks'
- ),
- 'imageusage' => array (
- 'code' => 'iu',
- 'prefix' => 'il',
- 'linktbl' => 'imagelinks'
- )
- );
-
- public function __construct($query, $moduleName) {
- $code = $prefix = $linktbl = null;
- extract($this->backlinksSettings[$moduleName]);
-
- parent :: __construct($query, $moduleName, $code);
- $this->bl_ns = $prefix . '_namespace';
- $this->bl_from = $prefix . '_from';
- $this->bl_tables = array (
- $linktbl,
- 'page'
- );
- $this->bl_code = $code;
-
- $this->hasNS = $moduleName !== 'imageusage';
- if ($this->hasNS) {
- $this->bl_title = $prefix . '_title';
- $this->bl_sort = "{$this->bl_ns}, {$this->bl_title}, {$this->bl_from}";
- $this->bl_fields = array (
- $this->bl_ns,
- $this->bl_title
- );
- } else {
- $this->bl_title = $prefix . '_to';
- $this->bl_sort = "{$this->bl_title}, {$this->bl_from}";
- $this->bl_fields = array (
- $this->bl_title
- );
- }
- }
-
- public function execute() {
- $this->run();
- }
-
- public function executeGenerator($resultPageSet) {
- $this->run($resultPageSet);
- }
-
- private function run($resultPageSet = null) {
- $this->params = $this->extractRequestParams();
-
- $redirect = $this->params['redirect'];
- if ($redirect)
- $this->dieDebug('Redirect has not been implemented', 'notimplemented');
-
- $this->processContinue();
-
- $this->addFields($this->bl_fields);
- if (is_null($resultPageSet))
- $this->addFields(array (
- 'page_id',
- 'page_namespace',
- 'page_title'
- ));
- else
- $this->addFields($resultPageSet->getPageTableFields()); // will include page_id
-
- $this->addTables($this->bl_tables);
- $this->addWhere($this->bl_from . '=page_id');
-
- if ($this->hasNS)
- $this->addWhereFld($this->bl_ns, $this->rootTitle->getNamespace());
- $this->addWhereFld($this->bl_title, $this->rootTitle->getDBkey());
- $this->addWhereFld('page_namespace', $this->params['namespace']);
-
- if($this->params['filterredir'] == 'redirects')
- $this->addWhereFld('page_is_redirect', 1);
- if($this->params['filterredir'] == 'nonredirects')
- $this->addWhereFld('page_is_redirect', 0);
-
- $limit = $this->params['limit'];
- $this->addOption('LIMIT', $limit +1);
- $this->addOption('ORDER BY', $this->bl_sort);
-
- $db = $this->getDB();
- if (!is_null($this->params['continue'])) {
- $plfrm = intval($this->contID);
- if ($this->contLevel == 0) {
- // For the first level, there is only one target title, so no need for complex filtering
- $this->addWhere($this->bl_from . '>=' . $plfrm);
- } else {
- $ns = $this->contTitle->getNamespace();
- $t = $db->addQuotes($this->contTitle->getDBkey());
- $whereWithoutNS = "{$this->bl_title}>$t OR ({$this->bl_title}=$t AND {$this->bl_from}>=$plfrm))";
-
- if ($this->hasNS)
- $this->addWhere("{$this->bl_ns}>$ns OR ({$this->bl_ns}=$ns AND ($whereWithoutNS)");
- else
- $this->addWhere($whereWithoutNS);
- }
- }
-
- $res = $this->select(__METHOD__);
-
- $count = 0;
- $data = array ();
- while ($row = $db->fetchObject($res)) {
- if (++ $count > $limit) {
- // We've reached the one extra which shows that there are additional pages to be had. Stop here...
- if ($redirect) {
- $ns = $row-> { $this->bl_ns };
- $t = $row-> { $this->bl_title };
- $continue = $this->getContinueRedirStr(false, 0, $ns, $t, $row->page_id);
- } else
- $continue = $this->getContinueStr($row->page_id);
- // TODO: Security issue - if the user has no right to view next title, it will still be shown
- $this->setContinueEnumParameter('continue', $continue);
- break;
- }
-
- if (is_null($resultPageSet)) {
- $vals = $this->extractRowInfo($row);
- if ($vals)
- $data[] = $vals;
- } else {
- $resultPageSet->processDbRow($row);
- }
- }
- $db->freeResult($res);
-
- if (is_null($resultPageSet)) {
- $result = $this->getResult();
- $result->setIndexedTagName($data, $this->bl_code);
- $result->addValue('query', $this->getModuleName(), $data);
- }
- }
-
- private function extractRowInfo($row) {
-
- $vals = array();
- $vals['pageid'] = intval($row->page_id);
- ApiQueryBase :: addTitleInfo($vals, Title :: makeTitle($row->page_namespace, $row->page_title));
-
- return $vals;
- }
-
- protected function processContinue() {
- $pageSet = $this->getPageSet();
- $count = $pageSet->getTitleCount();
-
- if (!is_null($this->params['continue'])) {
- $this->parseContinueParam();
-
- // Skip all completed links
-
- } else {
- $title = $this->params['title'];
- if (!is_null($title)) {
- $this->rootTitle = Title :: newFromText($title);
- } else { // This case is obsolete. Will support this for a while
- if ($count !== 1)
- $this->dieUsage("The {$this->getModuleName()} query requires one title to start", 'bad_title_count');
- $this->rootTitle = current($pageSet->getTitles()); // only one title there
- $this->setWarning('Using titles parameter is obsolete for this list. Use ' . $this->encodeParamName('title') . ' instead.');
- }
- }
-
- // only image titles are allowed for the root
- if (!$this->hasNS && $this->rootTitle->getNamespace() !== NS_IMAGE)
- $this->dieUsage("The title for {$this->getModuleName()} query must be an image", 'bad_image_title');
- }
-
- protected function parseContinueParam() {
- $continueList = explode('|', $this->params['continue']);
- if ($this->params['redirect']) {
- //
- // expected redirect-mode parameter:
- // ns|db_key|step|level|ns|db_key|id
- // ns+db_key -- the root title
- // step = 1 or 2 - which step to continue from - 1-titles, 2-redirects
- // level -- how many levels to follow before starting enumerating.
- // if level > 0 -- ns+title to continue from, otherwise skip these
- // id = last page_id to continue from
- //
- if (count($continueList) > 4) {
- $rootNs = intval($continueList[0]);
- if (($rootNs !== 0 || $continueList[0] === '0') && !empty ($continueList[1])) {
- $this->rootTitle = Title :: makeTitleSafe($rootNs, $continueList[1]);
- if ($this->rootTitle) {
-
- $step = intval($continueList[2]);
- if ($step === 1 || $step === 2) {
- $this->contRedirs = ($step === 2);
-
- $level = intval($continueList[3]);
- if ($level !== 0 || $continueList[3] === '0') {
- $this->contLevel = $level;
-
- if ($level === 0) {
- if (count($continueList) === 5) {
- $contID = intval($continueList[4]);
- if ($contID !== 0 || $continueList[4] === '0') {
- $this->contID = $contID;
- return; // done
- }
- }
- } else {
- if (count($continueList) === 7) {
- $contNs = intval($continueList[4]);
- if (($contNs !== 0 || $continueList[4] === '0') && !empty ($continueList[5])) {
- $this->contTitle = Title :: makeTitleSafe($contNs, $continueList[5]);
-
- $contID = intval($continueList[6]);
- if ($contID !== 0 || $continueList[6] === '0') {
- $this->contID = $contID;
- return; // done
- }
- }
- }
- }
- }
- }
- }
- }
- }
- } else {
- //
- // expected non-redirect-mode parameter:
- // ns|db_key|id
- // ns+db_key -- the root title
- // id = last page_id to continue from
- //
- if (count($continueList) === 3) {
- $rootNs = intval($continueList[0]);
- if (($rootNs !== 0 || $continueList[0] === '0') && !empty ($continueList[1])) {
- $this->rootTitle = Title :: makeTitleSafe($rootNs, $continueList[1]);
- if ($this->rootTitle) {
-
- $contID = intval($continueList[2]);
- if ($contID !== 0) {
- $this->contID = $contID;
- return; // done
- }
- }
- }
- }
- }
-
- $this->dieUsage("Invalid continue param. You should pass the original value returned by the previous query", "_badcontinue");
- }
-
- protected function getContinueStr($lastPageID) {
- return $this->rootTitle->getNamespace() .
- '|' . $this->rootTitle->getDBkey() .
- '|' . $lastPageID;
- }
-
- protected function getContinueRedirStr($isRedirPhase, $level, $ns, $title, $lastPageID) {
- return $this->rootTitle->getNamespace() .
- '|' . $this->rootTitle->getDBkey() .
- '|' . ($isRedirPhase ? 1 : 2) .
- '|' . $level .
- ($level > 0 ? ('|' . $ns . '|' . $title) : '') .
- '|' . $lastPageID;
- }
-
- protected function getAllowedParams() {
-
- return array (
- 'title' => null,
- 'continue' => null,
- 'namespace' => array (
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_TYPE => 'namespace'
- ),
- 'filterredir' => array(
- ApiBase :: PARAM_DFLT => 'all',
- ApiBase :: PARAM_TYPE => array(
- 'all',
- 'redirects',
- 'nonredirects'
- )
- ),
- 'redirect' => false,
- 'limit' => array (
- ApiBase :: PARAM_DFLT => 10,
- ApiBase :: PARAM_TYPE => 'limit',
- ApiBase :: PARAM_MIN => 1,
- ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
- ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
- )
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'title' => 'Title to search. If null, titles= parameter will be used instead, but will be obsolete soon.',
- 'continue' => 'When more results are available, use this to continue.',
- 'namespace' => 'The namespace to enumerate.',
- 'filterredir' => 'How to filter for redirects',
- 'redirect' => 'If linking page is a redirect, find all pages that link to that redirect (not implemented)',
- 'limit' => 'How many total pages to return.'
- );
- }
-
- protected function getDescription() {
- switch ($this->getModuleName()) {
- case 'backlinks' :
- return 'Find all pages that link to the given page';
- case 'embeddedin' :
- return 'Find all pages that embed (transclude) the given title';
- case 'imageusage' :
- return 'Find all pages that use the given image title.';
- default :
- ApiBase :: dieDebug(__METHOD__, 'Unknown module name');
- }
- }
-
- protected function getExamples() {
- static $examples = array (
- 'backlinks' => array (
- "api.php?action=query&list=backlinks&bltitle=Main%20Page",
- "api.php?action=query&generator=backlinks&gbltitle=Main%20Page&prop=info"
- ),
- 'embeddedin' => array (
- "api.php?action=query&list=embeddedin&eititle=Template:Stub",
- "api.php?action=query&generator=embeddedin&geititle=Template:Stub&prop=info"
- ),
- 'imageusage' => array (
- "api.php?action=query&list=imageusage&iutitle=Image:Albert%20Einstein%20Head.jpg",
- "api.php?action=query&generator=imageusage&giutitle=Image:Albert%20Einstein%20Head.jpg&prop=info"
- )
- );
-
- return $examples[$this->getModuleName()];
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryBacklinks.php 27562 2007-11-16 22:50:59Z brion $';
- }
-}
-
+++ /dev/null
-<?php
-
-/*
- * Created on Sep 7, 2006
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ('ApiBase.php');
-}
-
-/**
- * This is a base class for all Query modules.
- * It provides some common functionality such as constructing various SQL queries.
- *
- * @addtogroup API
- */
-abstract class ApiQueryBase extends ApiBase {
-
- private $mQueryModule, $mDb, $tables, $where, $fields, $options;
-
- public function __construct($query, $moduleName, $paramPrefix = '') {
- parent :: __construct($query->getMain(), $moduleName, $paramPrefix);
- $this->mQueryModule = $query;
- $this->mDb = null;
- $this->resetQueryParams();
- }
-
- protected function resetQueryParams() {
- $this->tables = array ();
- $this->where = array ();
- $this->fields = array ();
- $this->options = array ();
- }
-
- protected function addTables($tables, $alias = null) {
- if (is_array($tables)) {
- if (!is_null($alias))
- ApiBase :: dieDebug(__METHOD__, 'Multiple table aliases not supported');
- $this->tables = array_merge($this->tables, $tables);
- } else {
- if (!is_null($alias))
- $tables = $this->getDB()->tableName($tables) . ' ' . $alias;
- $this->tables[] = $tables;
- }
- }
-
- protected function addFields($value) {
- if (is_array($value))
- $this->fields = array_merge($this->fields, $value);
- else
- $this->fields[] = $value;
- }
-
- protected function addFieldsIf($value, $condition) {
- if ($condition) {
- $this->addFields($value);
- return true;
- }
- return false;
- }
-
- protected function addWhere($value) {
- if (is_array($value))
- $this->where = array_merge($this->where, $value);
- else
- $this->where[] = $value;
- }
-
- protected function addWhereIf($value, $condition) {
- if ($condition) {
- $this->addWhere($value);
- return true;
- }
- return false;
- }
-
- protected function addWhereFld($field, $value) {
- if (!is_null($value))
- $this->where[$field] = $value;
- }
-
- protected function addWhereRange($field, $dir, $start, $end) {
- $isDirNewer = ($dir === 'newer');
- $after = ($isDirNewer ? '>=' : '<=');
- $before = ($isDirNewer ? '<=' : '>=');
- $db = $this->getDB();
-
- if (!is_null($start))
- $this->addWhere($field . $after . $db->addQuotes($start));
-
- if (!is_null($end))
- $this->addWhere($field . $before . $db->addQuotes($end));
-
- $this->addOption('ORDER BY', $field . ($isDirNewer ? '' : ' DESC'));
- }
-
- protected function addOption($name, $value = null) {
- if (is_null($value))
- $this->options[] = $name;
- else
- $this->options[$name] = $value;
- }
-
- protected function select($method) {
-
- // getDB has its own profileDBIn/Out calls
- $db = $this->getDB();
-
- $this->profileDBIn();
- $res = $db->select($this->tables, $this->fields, $this->where, $method, $this->options);
- $this->profileDBOut();
-
- return $res;
- }
-
- public static function addTitleInfo(&$arr, $title, $prefix='') {
- $arr[$prefix . 'ns'] = intval($title->getNamespace());
- $arr[$prefix . 'title'] = $title->getPrefixedText();
- }
-
- /**
- * Override this method to request extra fields from the pageSet
- * using $pageSet->requestField('fieldName')
- */
- public function requestExtraData($pageSet) {
- }
-
- /**
- * Get the main Query module
- */
- public function getQuery() {
- return $this->mQueryModule;
- }
-
- /**
- * Add sub-element under the page element with the given pageId.
- */
- protected function addPageSubItems($pageId, $data) {
- $result = $this->getResult();
- $result->setIndexedTagName($data, $this->getModulePrefix());
- $result->addValue(array ('query', 'pages', intval($pageId)),
- $this->getModuleName(),
- $data);
- }
-
- protected function setContinueEnumParameter($paramName, $paramValue) {
-
- $paramName = $this->encodeParamName($paramName);
- $msg = array( $paramName => $paramValue );
-
-// This is an alternative continue format as a part of the URL string
-// ApiResult :: setContent($msg, $paramName . '=' . urlencode($paramValue));
-
- $this->getResult()->addValue('query-continue', $this->getModuleName(), $msg);
- }
-
- /**
- * Get the Query database connection (readonly)
- */
- protected function getDB() {
- if (is_null($this->mDb))
- $this->mDb = $this->getQuery()->getDB();
- return $this->mDb;
- }
-
- /**
- * Selects the query database connection with the given name.
- * If no such connection has been requested before, it will be created.
- * Subsequent calls with the same $name will return the same connection
- * as the first, regardless of $db or $groups new values.
- */
- public function selectNamedDB($name, $db, $groups) {
- $this->mDb = $this->getQuery()->getNamedDB($name, $db, $groups);
- }
-
- /**
- * Get the PageSet object to work on
- * @return ApiPageSet data
- */
- protected function getPageSet() {
- return $this->getQuery()->getPageSet();
- }
-
- /**
- * This is a very simplistic utility function
- * to convert a non-namespaced title string to a db key.
- * It will replace all ' ' with '_'
- */
- public static function titleToKey($title) {
- return str_replace(' ', '_', $title);
- }
-
- public static function keyToTitle($key) {
- return str_replace('_', ' ', $key);
- }
-
- public function getTokenFlag($tokenArr, $action) {
- if (in_array($action, $tokenArr)) {
- global $wgUser;
- if ($wgUser->isAllowed($action))
- return true;
- else
- $this->dieUsage("Action '$action' is not allowed for the current user", 'permissiondenied');
- }
- return false;
- }
-
- public static function getBaseVersion() {
- return __CLASS__ . ': $Id: ApiQueryBase.php 24533 2007-08-01 22:46:22Z yurik $';
- }
-}
-
-/**
- * @addtogroup API
- */
-abstract class ApiQueryGeneratorBase extends ApiQueryBase {
-
- private $mIsGenerator;
-
- public function __construct($query, $moduleName, $paramPrefix = '') {
- parent :: __construct($query, $moduleName, $paramPrefix);
- $this->mIsGenerator = false;
- }
-
- public function setGeneratorMode() {
- $this->mIsGenerator = true;
- }
-
- /**
- * Overrides base class to prepend 'g' to every generator parameter
- */
- public function encodeParamName($paramName) {
- if ($this->mIsGenerator)
- return 'g' . parent :: encodeParamName($paramName);
- else
- return parent :: encodeParamName($paramName);
- }
-
- /**
- * Execute this module as a generator
- * @param $resultPageSet PageSet: All output should be appended to this object
- */
- public abstract function executeGenerator($resultPageSet);
-}
-
+++ /dev/null
-<?php
-
-/*
- * Created on Sep 10, 2007
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
-}
-
-/**
- * Query module to enumerate all available pages.
- *
- * @addtogroup API
- */
-class ApiQueryBlocks extends ApiQueryBase {
-
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'bk');
- }
-
- public function execute() {
- $this->run();
- }
-
- private function run() {
- global $wgUser;
-
- $params = $this->extractRequestParams();
- $prop = array_flip($params['prop']);
- $fld_id = isset($prop['id']);
- $fld_user = isset($prop['user']);
- $fld_by = isset($prop['by']);
- $fld_timestamp = isset($prop['timestamp']);
- $fld_expiry = isset($prop['expiry']);
- $fld_reason = isset($prop['reason']);
- $fld_range = isset($prop['range']);
- $fld_flags = isset($prop['flags']);
-
- $result = $this->getResult();
- $pageSet = $this->getPageSet();
- $titles = $pageSet->getTitles();
- $data = array();
-
- $this->addTables('ipblocks');
- if($fld_id)
- $this->addFields('ipb_id');
- if($fld_user)
- $this->addFields(array('ipb_address', 'ipb_user'));
- if($fld_by)
- {
- $this->addTables('user');
- $this->addFields(array('ipb_by', 'user_name'));
- $this->addWhere('user_id = ipb_by');
- }
- if($fld_timestamp)
- $this->addFields('ipb_timestamp');
- if($fld_expiry)
- $this->addFields('ipb_expiry');
- if($fld_reason)
- $this->addFields('ipb_reason');
- if($fld_range)
- $this->addFields(array('ipb_range_start', 'ipb_range_end'));
- if($fld_flags)
- $this->addFields(array('ipb_auto', 'ipb_anon_only', 'ipb_create_account', 'ipb_enable_autoblock', 'ipb_block_email', 'ipb_deleted'));
-
- $this->addOption('LIMIT', $params['limit'] + 1);
- $this->addWhereRange('ipb_timestamp', $params['dir'], $params['start'], $params['end']);
- if(isset($params['ids']))
- $this->addWhere(array('ipb_id' => $params['ids']));
- if(isset($params['users']))
- $this->addWhere(array('ipb_address' => $params['users']));
- if(!$wgUser->isAllowed('oversight'))
- $this->addWhere(array('ipb_deleted' => 0));
-
- // Purge expired entries on one in every 10 queries
- if(!mt_rand(0, 10))
- Block::purgeExpired();
-
- $res = $this->select(__METHOD__);
- $db = wfGetDB();
-
- $count = 0;
- while($row = $db->fetchObject($res))
- {
- if($count++ == $params['limit'])
- {
- // We've had enough
- $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->ipb_timestamp));
- break;
- }
- $block = array();
- if($fld_id)
- $block['id'] = $row->ipb_id;
- if($fld_user)
- {
- $block['user'] = $row->ipb_address;
- $block['userid'] = $row->ipb_user;
- }
- if($fld_by)
- {
- $block['by'] = $row->user_name;
- $block['byuserid'] = $row->ipb_by;
- }
- if($fld_timestamp)
- $block['timestamp'] = wfTimestamp(TS_ISO_8601, $row->ipb_timestamp);
- if($fld_expiry)
- $block['expiry'] = Block::decodeExpiry($row->ipb_expiry, TS_ISO_8601);
- if($fld_reason)
- $block['reason'] = $row->ipb_reason;
- if($fld_range)
- {
- $block['rangestart'] = $this->convertHexIP($row->ipb_range_start);
- $block['rangeend'] = $this->convertHexIP($row->ipb_range_end);
- }
- if($fld_flags)
- {
- // For clarity, these flags use the same names as their action=block counterparts
- if($row->ipb_auto)
- $block['automatic'] = '';
- if($row->ipb_anon_only)
- $block['anononly'] = '';
- if($row->ipb_create_account)
- $block['nocreate'] = '';
- if($row->ipb_enable_autoblock)
- $block['autoblock'] = '';
- if($row->ipb_block_email)
- $block['noemail'] = '';
- if($row->ipb_deleted)
- $block['hidden'] = '';
- }
- $data[] = $block;
- }
- $result->setIndexedTagName($data, 'block');
- $result->addValue('query', $this->getModuleName(), $data);
- }
-
- protected function convertHexIP($ip)
- {
- // Converts a hexadecimal IP to nnn.nnn.nnn.nnn format
- $dec = wfBaseConvert($ip, 16, 10);
- $parts[0] = (int)($dec / (256*256*256));
- $dec %= 256*256*256;
- $parts[1] = (int)($dec / (256*256));
- $dec %= 256*256;
- $parts[2] = (int)($dec / 256);
- $parts[3] = $dec % 256;
- return implode('.', $parts);
- }
-
- protected function getAllowedParams() {
- return array (
- 'start' => array(
- ApiBase :: PARAM_TYPE => 'timestamp'
- ),
- 'end' => array(
- ApiBase :: PARAM_TYPE => 'timestamp',
- ),
- 'dir' => array(
- ApiBase :: PARAM_TYPE => array(
- 'newer',
- 'older'
- ),
- ApiBase :: PARAM_DFLT => 'older'
- ),
- 'ids' => array(
- ApiBase :: PARAM_TYPE => 'integer',
- ApiBase :: PARAM_ISMULTI => true
- ),
- 'users' => array(
- ApiBase :: PARAM_ISMULTI => true
- ),
- 'limit' => array(
- ApiBase :: PARAM_DFLT => 10,
- ApiBase :: PARAM_TYPE => 'limit',
- ApiBase :: PARAM_MIN => 1,
- ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
- ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
- ),
- 'prop' => array(
- ApiBase :: PARAM_DFLT => 'id|user|by|timestamp|expiry|reason|flags',
- ApiBase :: PARAM_TYPE => array(
- 'id',
- 'user',
- 'by',
- 'timestamp',
- 'expiry',
- 'reason',
- 'range',
- 'flags'
- ),
- ApiBase :: PARAM_ISMULTI => true
- )
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'start' => 'The timestamp to start enumerating from',
- 'end' => 'The timestamp to stop enumerating at',
- 'dir' => 'The direction in which to enumerate',
- 'ids' => 'Pipe-separated list of block IDs to list (optional)',
- 'users' => 'Pipe-separated list of users to search for (optional)',
- 'limit' => 'The maximum amount of blocks to list',
- 'prop' => 'Which properties to get',
- );
- }
-
- protected function getDescription() {
- return 'List all blocked users and IP addresses.';
- }
-
- protected function getExamples() {
- return array (
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryBlocks.php 28209 2007-12-06 16:06:22Z vasilievvv $';
- }
-}
+++ /dev/null
-<?php
-
-/*
- * Created on May 13, 2007
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ("ApiQueryBase.php");
-}
-
-/**
- * A query module to enumerate categories the set of pages belong to.
- *
- * @addtogroup API
- */
-class ApiQueryCategories extends ApiQueryGeneratorBase {
-
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'cl');
- }
-
- public function execute() {
- $this->run();
- }
-
- public function executeGenerator($resultPageSet) {
- $this->run($resultPageSet);
- }
-
- private function run($resultPageSet = null) {
-
- if ($this->getPageSet()->getGoodTitleCount() == 0)
- return; // nothing to do
-
- $params = $this->extractRequestParams();
- $prop = $params['prop'];
-
- $this->addFields(array (
- 'cl_from',
- 'cl_to'
- ));
-
- $fld_sortkey = false;
- if (!is_null($prop)) {
- foreach($prop as $p) {
- switch ($p) {
- case 'sortkey':
- $this->addFields('cl_sortkey');
- $fld_sortkey = true;
- break;
- default :
- ApiBase :: dieDebug(__METHOD__, "Unknown prop=$p");
- }
- }
- }
-
- $this->addTables('categorylinks');
- $this->addWhereFld('cl_from', array_keys($this->getPageSet()->getGoodTitles()));
- $this->addOption('ORDER BY', "cl_from, cl_to");
-
- $db = $this->getDB();
- $res = $this->select(__METHOD__);
-
- if (is_null($resultPageSet)) {
-
- $data = array();
- $lastId = 0; // database has no ID 0
- while ($row = $db->fetchObject($res)) {
- if ($lastId != $row->cl_from) {
- if($lastId != 0) {
- $this->addPageSubItems($lastId, $data);
- $data = array();
- }
- $lastId = $row->cl_from;
- }
-
- $title = Title :: makeTitle(NS_CATEGORY, $row->cl_to);
-
- $vals = array();
- ApiQueryBase :: addTitleInfo($vals, $title);
- if ($fld_sortkey)
- $vals['sortkey'] = $row->cl_sortkey;
-
- $data[] = $vals;
- }
-
- if($lastId != 0) {
- $this->addPageSubItems($lastId, $data);
- }
-
- } else {
-
- $titles = array();
- while ($row = $db->fetchObject($res)) {
- $titles[] = Title :: makeTitle(NS_CATEGORY, $row->cl_to);
- }
- $resultPageSet->populateFromTitles($titles);
- }
-
- $db->freeResult($res);
- }
-
- protected function getAllowedParams() {
- return array (
- 'prop' => array (
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_TYPE => array (
- 'sortkey',
- )
- )
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'prop' => 'Which additional properties to get for each category.',
- );
- }
-
- protected function getDescription() {
- return 'List all categories the page(s) belong to';
- }
-
- protected function getExamples() {
- return array (
- "Get a list of categories [[Albert Einstein]] belongs to:",
- " api.php?action=query&prop=categories&titles=Albert%20Einstein",
- "Get information about all categories used in the [[Albert Einstein]]:",
- " api.php?action=query&generator=categories&titles=Albert%20Einstein&prop=info"
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryCategories.php 24092 2007-07-14 19:04:31Z yurik $';
- }
-}
-
+++ /dev/null
-<?php
-
-/*
- * Created on June 14, 2007
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ("ApiQueryBase.php");
-}
-
-/**
- * A query module to enumerate pages that belong to a category.
- *
- * @addtogroup API
- */
-class ApiQueryCategoryMembers extends ApiQueryGeneratorBase {
-
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'cm');
- }
-
- public function execute() {
- $this->run();
- }
-
- public function executeGenerator($resultPageSet) {
- $this->run($resultPageSet);
- }
-
- private function run($resultPageSet = null) {
-
- $params = $this->extractRequestParams();
-
- $category = $params['category'];
- if (is_null($category))
- $this->dieUsage("Category parameter is required", 'param_category');
- $categoryTitle = Title::makeTitleSafe( NS_CATEGORY, $category );
- if ( is_null( $categoryTitle ) )
- $this->dieUsage("Category name $category is not valid", 'param_category');
-
- $prop = array_flip($params['prop']);
- $fld_ids = isset($prop['ids']);
- $fld_title = isset($prop['title']);
- $fld_sortkey = isset($prop['sortkey']);
- $fld_timestamp = isset($prop['timestamp']);
-
- if (is_null($resultPageSet)) {
- $this->addFields(array('cl_from', 'cl_sortkey', 'page_namespace', 'page_title'));
- $this->addFieldsIf('page_id', $fld_ids);
- } else {
- $this->addFields($resultPageSet->getPageTableFields()); // will include page_ id, ns, title
- $this->addFields(array('cl_from', 'cl_sortkey'));
- }
-
- $this->addFieldsIf('cl_timestamp', $fld_timestamp);
- $this->addTables(array('page','categorylinks')); // must be in this order for 'USE INDEX'
- // Not needed after bug 10280 is applied to servers
- if($params['sort'] == 'timestamp')
- {
- $this->addOption('USE INDEX', 'cl_timestamp');
- $this->addOption('ORDER BY', 'cl_to, cl_timestamp' . ($params['dir'] == 'desc' ? ' DESC' : ''));
- }
- else
- {
- $this->addOption('USE INDEX', 'cl_sortkey');
- $this->addOption('ORDER BY', 'cl_to, cl_sortkey' . ($params['dir'] == 'desc' ? ' DESC' : '') . ', cl_from');
- }
-
- $this->addWhere('cl_from=page_id');
- $this->setContinuation($params['continue']);
- $this->addWhereFld('cl_to', $categoryTitle->getDBkey());
- $this->addWhereFld('page_namespace', $params['namespace']);
-
- $limit = $params['limit'];
- $this->addOption('LIMIT', $limit +1);
-
- $db = $this->getDB();
-
- $data = array ();
- $count = 0;
- $lastSortKey = null;
- $res = $this->select(__METHOD__);
- while ($row = $db->fetchObject($res)) {
- if (++ $count > $limit) {
- // We've reached the one extra which shows that there are additional pages to be had. Stop here...
- // TODO: Security issue - if the user has no right to view next title, it will still be shown
- $this->setContinueEnumParameter('continue', $this->getContinueStr($row, $lastSortKey));
- break;
- }
-
- $lastSortKey = $row->cl_sortkey; // detect duplicate sortkeys
-
- if (is_null($resultPageSet)) {
- $vals = array();
- if ($fld_ids)
- $vals['pageid'] = intval($row->page_id);
- if ($fld_title) {
- $title = Title :: makeTitle($row->page_namespace, $row->page_title);
- $vals['ns'] = intval($title->getNamespace());
- $vals['title'] = $title->getPrefixedText();
- }
- if ($fld_sortkey)
- $vals['sortkey'] = $row->cl_sortkey;
- if ($fld_timestamp)
- $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->cl_timestamp);
- $data[] = $vals;
- } else {
- $resultPageSet->processDbRow($row);
- }
- }
- $db->freeResult($res);
-
- if (is_null($resultPageSet)) {
- $this->getResult()->setIndexedTagName($data, 'cm');
- $this->getResult()->addValue('query', $this->getModuleName(), $data);
- }
- }
-
- private function getContinueStr($row, $lastSortKey) {
- $ret = $row->cl_sortkey . '|';
- if ($row->cl_sortkey == $lastSortKey) // duplicate sort key, add cl_from
- $ret .= $row->cl_from;
- return $ret;
- }
-
- /**
- * Add DB WHERE clause to continue previous query based on 'continue' parameter
- */
- private function setContinuation($continue) {
- if (is_null($continue))
- return; // This is not a continuation request
-
- $continueList = explode('|', $continue);
- $hasError = count($continueList) != 2;
- $from = 0;
- if (!$hasError && strlen($continueList[1]) > 0) {
- $from = intval($continueList[1]);
- $hasError = ($from == 0);
- }
-
- if ($hasError)
- $this->dieUsage("Invalid continue param. You should pass the original value returned by the previous query", "badcontinue");
-
- $encSortKey = $this->getDB()->addQuotes($continueList[0]);
- $encFrom = $this->getDB()->addQuotes($from);
-
- if ($from != 0) {
- // Duplicate sort key continue
- $this->addWhere( "cl_sortkey>$encSortKey OR (cl_sortkey=$encSortKey AND cl_from>=$encFrom)" );
- } else {
- $this->addWhere( "cl_sortkey>=$encSortKey" );
- }
- }
-
- protected function getAllowedParams() {
- return array (
- 'category' => null,
- 'prop' => array (
- ApiBase :: PARAM_DFLT => 'ids|title',
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_TYPE => array (
- 'ids',
- 'title',
- 'sortkey',
- 'timestamp',
- )
- ),
- 'namespace' => array (
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_TYPE => 'namespace',
- ),
- 'continue' => null,
- 'limit' => array (
- ApiBase :: PARAM_TYPE => 'limit',
- ApiBase :: PARAM_DFLT => 10,
- ApiBase :: PARAM_MIN => 1,
- ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
- ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
- ),
- 'sort' => array(
- ApiBase :: PARAM_DFLT => 'sortkey',
- ApiBase :: PARAM_TYPE => array(
- 'sortkey',
- 'timestamp'
- )
- ),
- 'dir' => array(
- ApiBase :: PARAM_DFLT => 'asc',
- ApiBase :: PARAM_TYPE => array(
- 'asc',
- 'desc'
- )
- )
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'category' => 'Which category to enumerate (required)',
- 'prop' => 'What pieces of information to include',
- 'namespace' => 'Only include pages in these namespaces',
- 'sort' => 'Property to sort by',
- 'dir' => 'In which direction to sort',
- 'continue' => 'For large categories, give the value retured from previous query',
- 'limit' => 'The maximum number of pages to return.',
- );
- }
-
- protected function getDescription() {
- return 'List all pages in a given category';
- }
-
- protected function getExamples() {
- return array (
- "Get first 10 pages in the categories [[Physics]]:",
- " api.php?action=query&list=categorymembers&cmcategory=Physics",
- "Get page info about first 10 pages in the categories [[Physics]]:",
- " api.php?action=query&generator=categorymembers&gcmcategory=Physics&prop=info",
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryCategoryMembers.php 25726 2007-09-10 14:17:33Z catrope $';
- }
-}
-
+++ /dev/null
-<?php
-
-/*
- * Created on Jul 2, 2007
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
-}
-
-/**
- * Query module to enumerate all available pages.
- *
- * @addtogroup API
- */
-class ApiQueryDeletedrevs extends ApiQueryBase {
-
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'dr');
- }
-
- public function execute() {
-
- global $wgUser;
- // Before doing anything at all, let's check permissions
- if(!$wgUser->isAllowed('deletedhistory'))
- $this->dieUsage('You don\'t have permission to view deleted revision information', 'permissiondenied');
-
- $db = $this->getDB();
- $params = $this->extractRequestParams();
- $prop = array_flip($params['prop']);
- $fld_revid = isset($prop['revid']);
- $fld_user = isset($prop['user']);
- $fld_comment = isset($prop['comment']);
- $fld_minor = isset($prop['minor']);
- $fld_len = isset($prop['len']);
- $fld_content = isset($prop['content']);
- $fld_token = isset($prop['token']);
-
- $result = $this->getResult();
- $pageSet = $this->getPageSet();
- $titles = $pageSet->getTitles();
- $data = array();
-
- $this->addTables('archive');
- $this->addFields(array('ar_title', 'ar_namespace', 'ar_timestamp'));
- if($fld_revid)
- $this->addFields('ar_rev_id');
- if($fld_user)
- $this->addFields('ar_user_text');
- if($fld_comment)
- $this->addFields('ar_comment');
- if($fld_minor)
- $this->addFields('ar_minor_edit');
- if($fld_len)
- $this->addFields('ar_len');
- if($fld_content)
- {
- $this->addTables('text');
- $this->addFields(array('ar_text', 'ar_text_id', 'old_text', 'old_flags'));
- $this->addWhere('ar_text_id = old_id');
-
- // This also means stricter limits and stricter restrictions
- if(!$wgUser->isAllowed('undelete'))
- $this->dieUsage('You don\'t have permission to view deleted revision content', 'permissiondenied');
- $userMax = ApiBase :: LIMIT_SML1;
- $botMax = ApiBase :: LIMIT_SML2;
- $this->validateLimit('limit', $params['limit'], 1, $userMax, $botMax);
- }
- if($fld_token)
- // Undelete tokens are identical for all pages, so we cache one here
- $token = $wgUser->editToken();
-
- // We need a custom WHERE clause that matches all titles.
- if(count($titles) > 0)
- {
- $lb = new LinkBatch($titles);
- $where = $lb->constructSet('ar', $db);
- $this->addWhere($where);
- }
-
- $this->addOption('LIMIT', $params['limit'] + 1);
- $this->addWhereRange('ar_timestamp', $params['dir'], $params['start'], $params['end']);
- if(isset($params['namespace']))
- $this->addWhereFld('ar_namespace', $params['namespace']);
- $res = $this->select(__METHOD__);
- $pages = array();
- $count = 0;
- // First populate the $pages array
- while($row = $db->fetchObject($res))
- {
- if($count++ == $params['limit'])
- {
- // We've had enough
- $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->ar_timestamp));
- break;
- }
-
- $rev = array();
- $rev['timestamp'] = wfTimestamp(TS_ISO_8601, $row->ar_timestamp);
- if($fld_revid)
- $rev['revid'] = $row->ar_rev_id;
- if($fld_user)
- $rev['user'] = $row->ar_user_text;
- if($fld_comment)
- $rev['comment'] = $row->ar_comment;
- if($fld_minor)
- if($row->ar_minor_edit == 1)
- $rev['minor'] = '';
- if($fld_len)
- $rev['len'] = $row->ar_len;
- if($fld_content)
- ApiResult::setContent($rev, Revision::getRevisionText($row));
-
- $t = Title::makeTitle($row->ar_namespace, $row->ar_title);
- if(!isset($pages[$t->getPrefixedText()]))
- {
- $pages[$t->getPrefixedText()] = array(
- 'title' => $t->getPrefixedText(),
- 'ns' => intval($row->ar_namespace),
- 'revisions' => array($rev)
- );
- if($fld_token)
- $pages[$t->getPrefixedText()]['token'] = $token;
- }
- else
- $pages[$t->getPrefixedText()]['revisions'][] = $rev;
- }
- $db->freeResult($res);
-
- // We don't want entire pagenames as keys, so let's make this array indexed
- foreach($pages as $page)
- {
- $result->setIndexedTagName($page['revisions'], 'rev');
- $data[] = $page;
- }
- $result->setIndexedTagName($data, 'page');
- $result->addValue('query', $this->getModuleName(), $data);
- }
-
- protected function getAllowedParams() {
- return array (
- 'start' => array(
- ApiBase :: PARAM_TYPE => 'timestamp'
- ),
- 'end' => array(
- ApiBase :: PARAM_TYPE => 'timestamp',
- ),
- 'dir' => array(
- ApiBase :: PARAM_TYPE => array(
- 'newer',
- 'older'
- ),
- ApiBase :: PARAM_DFLT => 'older'
- ),
- 'namespace' => array(
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_TYPE => 'namespace'
- ),
- 'limit' => array(
- ApiBase :: PARAM_DFLT => 10,
- ApiBase :: PARAM_TYPE => 'limit',
- ApiBase :: PARAM_MIN => 1,
- ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
- ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
- ),
- 'prop' => array(
- ApiBase :: PARAM_DFLT => 'user|comment',
- ApiBase :: PARAM_TYPE => array(
- 'revid',
- 'user',
- 'comment',
- 'minor',
- 'len',
- 'content',
- 'token'
- ),
- ApiBase :: PARAM_ISMULTI => true
- )
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'start' => 'The timestamp to start enumerating from',
- 'end' => 'The timestamp to stop enumerating at',
- 'dir' => 'The direction in which to enumerate',
- 'namespace' => 'The namespaces to search in',
- 'limit' => 'The maximum amount of revisions to list',
- 'prop' => 'Which properties to get'
- );
- }
-
- protected function getDescription() {
- return 'List deleted revisions.';
- }
-
- protected function getExamples() {
- return array (
- 'List the first 50 deleted revisions in the Category and Category talk namespaces',
- ' api.php?action=query&list=deletedrevs&drdir=newer&drlimit=50&drnamespace=14|15',
- 'List the last deleted revisions of Main Page and Talk:Main Page, with content:',
- ' api.php?action=query&list=deletedrevs&titles=Main%20Page|Talk:Main%20Page&drprop=user|comment|content'
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryDeletedrevs.php 28209 2007-12-06 16:06:22Z vasilievvv $';
- }
-}
+++ /dev/null
-<?php
-
-/*
- * Created on July 7, 2007
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
-}
-
-/**
- * @addtogroup API
- */
-class ApiQueryExtLinksUsage extends ApiQueryGeneratorBase {
-
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'eu');
- }
-
- public function execute() {
- $this->run();
- }
-
- public function executeGenerator($resultPageSet) {
- $this->run($resultPageSet);
- }
-
- private function run($resultPageSet = null) {
-
- $params = $this->extractRequestParams();
-
- $protocol = $params['protocol'];
- $query = $params['query'];
- if (is_null($query))
- $this->dieUsage('Missing required query parameter', 'params');
-
- // Find the right prefix
- global $wgUrlProtocols;
- foreach ($wgUrlProtocols as $p) {
- if( substr( $p, 0, strlen( $protocol ) ) === $protocol ) {
- $protocol = $p;
- break;
- }
- }
-
- $likeQuery = LinkFilter::makeLike($query , $protocol);
- if (!$likeQuery)
- $this->dieUsage('Invalid query', 'bad_query');
- $likeQuery = substr($likeQuery, 0, strpos($likeQuery,'%')+1);
-
- $this->addTables(array('page','externallinks')); // must be in this order for 'USE INDEX'
- $this->addOption('USE INDEX', 'el_index');
-
- $db = $this->getDB();
- $this->addWhere('page_id=el_from');
- $this->addWhere('el_index LIKE ' . $db->addQuotes( $likeQuery ));
- $this->addWhereFld('page_namespace', $params['namespace']);
-
- $prop = array_flip($params['prop']);
- $fld_ids = isset($prop['ids']);
- $fld_title = isset($prop['title']);
- $fld_url = isset($prop['url']);
-
- if (is_null($resultPageSet)) {
- $this->addFields(array (
- 'page_id',
- 'page_namespace',
- 'page_title'
- ));
- $this->addFieldsIf('el_to', $fld_url);
- } else {
- $this->addFields($resultPageSet->getPageTableFields());
- }
-
- $limit = $params['limit'];
- $offset = $params['offset'];
- $this->addOption('LIMIT', $limit +1);
- if (isset ($offset))
- $this->addOption('OFFSET', $offset);
-
- $res = $this->select(__METHOD__);
-
- $data = array ();
- $count = 0;
- while ($row = $db->fetchObject($res)) {
- if (++ $count > $limit) {
- // We've reached the one extra which shows that there are additional pages to be had. Stop here...
- $this->setContinueEnumParameter('offset', $offset+$limit+1);
- break;
- }
-
- if (is_null($resultPageSet)) {
- $vals = array();
- if ($fld_ids)
- $vals['pageid'] = intval($row->page_id);
- if ($fld_title) {
- $title = Title :: makeTitle($row->page_namespace, $row->page_title);
- $vals['ns'] = intval($title->getNamespace());
- $vals['title'] = $title->getPrefixedText();
- }
- if ($fld_url)
- $vals['url'] = $row->el_to;
- $data[] = $vals;
- } else {
- $resultPageSet->processDbRow($row);
- }
- }
- $db->freeResult($res);
-
- if (is_null($resultPageSet)) {
- $result = $this->getResult();
- $result->setIndexedTagName($data, $this->getModulePrefix());
- $result->addValue('query', $this->getModuleName(), $data);
- }
- }
-
- protected function getAllowedParams() {
- global $wgUrlProtocols;
- $protocols = array();
- foreach ($wgUrlProtocols as $p) {
- $protocols[] = substr($p, 0, strpos($p,':'));
- }
-
- return array (
- 'prop' => array (
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_DFLT => 'ids|title|url',
- ApiBase :: PARAM_TYPE => array (
- 'ids',
- 'title',
- 'url'
- )
- ),
- 'offset' => array (
- ApiBase :: PARAM_TYPE => 'integer'
- ),
- 'protocol' => array (
- ApiBase :: PARAM_TYPE => $protocols,
- ApiBase :: PARAM_DFLT => 'http',
- ),
- 'query' => null,
- 'namespace' => array (
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_TYPE => 'namespace'
- ),
- 'limit' => array (
- ApiBase :: PARAM_DFLT => 10,
- ApiBase :: PARAM_TYPE => 'limit',
- ApiBase :: PARAM_MIN => 1,
- ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
- ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
- )
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'prop' => 'What pieces of information to include',
- 'offset' => 'Used for paging. Use the value returned for "continue"',
- 'protocol' => 'Protocol of the url',
- 'query' => 'Search string without protocol. See [[Special:LinkSearch]]',
- 'namespace' => 'The page namespace(s) to enumerate.',
- 'limit' => 'How many entries to return.'
- );
- }
-
- protected function getDescription() {
- return 'Enumerate pages that contain a given URL';
- }
-
- protected function getExamples() {
- return array (
- 'api.php?action=query&list=exturlusage&euquery=www.mediawiki.org'
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryExtLinksUsage.php 24694 2007-08-09 08:41:58Z yurik $';
- }
-}
+++ /dev/null
-<?php
-
-/*
- * Created on May 13, 2007
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ("ApiQueryBase.php");
-}
-
-/**
- * A query module to list all external URLs found on a given set of pages.
- *
- * @addtogroup API
- */
-class ApiQueryExternalLinks extends ApiQueryBase {
-
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'el');
- }
-
- public function execute() {
-
- $this->addFields(array (
- 'el_from',
- 'el_to'
- ));
-
- $this->addTables('externallinks');
- $this->addWhereFld('el_from', array_keys($this->getPageSet()->getGoodTitles()));
-
- $db = $this->getDB();
- $res = $this->select(__METHOD__);
-
- $data = array();
- $lastId = 0; // database has no ID 0
- while ($row = $db->fetchObject($res)) {
- if ($lastId != $row->el_from) {
- if($lastId != 0) {
- $this->addPageSubItems($lastId, $data);
- $data = array();
- }
- $lastId = $row->el_from;
- }
-
- $entry = array();
- ApiResult :: setContent($entry, $row->el_to);
- $data[] = $entry;
- }
-
- if($lastId != 0) {
- $this->addPageSubItems($lastId, $data);
- }
-
- $db->freeResult($res);
- }
-
- protected function getDescription() {
- return 'Returns all external urls (not interwikies) from the given page(s)';
- }
-
- protected function getExamples() {
- return array (
- "Get a list of external links on the [[Main Page]]:",
- " api.php?action=query&prop=extlinks&titles=Main%20Page",
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryExternalLinks.php 23819 2007-07-07 03:05:09Z yurik $';
- }
-}
-
+++ /dev/null
-<?php
-
-/*
- * Created on July 6, 2007
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
-}
-
-/**
- * A query action to get image information and upload history.
- *
- * @addtogroup API
- */
-class ApiQueryImageInfo extends ApiQueryBase {
-
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'ii');
- }
-
- public function execute() {
- $params = $this->extractRequestParams();
-
- $history = $params['history'];
-
- $prop = array_flip($params['prop']);
- $fld_timestamp = isset($prop['timestamp']);
- $fld_user = isset($prop['user']);
- $fld_comment = isset($prop['comment']);
- $fld_url = isset($prop['url']);
- $fld_size = isset($prop['size']);
- $fld_sha1 = isset($prop['sha1']);
- $fld_metadata = isset($prop['metadata']);
-
- $pageIds = $this->getPageSet()->getAllTitlesByNamespace();
- if (!empty($pageIds[NS_IMAGE])) {
- foreach ($pageIds[NS_IMAGE] as $dbKey => $pageId) {
-
- $title = Title :: makeTitle(NS_IMAGE, $dbKey);
- $img = wfFindFile($title);
-
- $data = array();
- if ( !$img ) {
- $repository = '';
- } else {
-
- $repository = $img->getRepoName();
-
- $isCur = true;
- while($line = $img->nextHistoryLine()) { // assignment
- $row = get_object_vars( $line );
- $vals = array();
- $prefix = $isCur ? 'img' : 'oi';
-
- if ($fld_timestamp)
- $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row["${prefix}_timestamp"]);
- if ($fld_user) {
- $vals['user'] = $row["${prefix}_user_text"];
- if(!$row["${prefix}_user"])
- $vals['anon'] = '';
- }
- if ($fld_size) {
- $vals['size'] = intval($row["{$prefix}_size"]);
- $vals['width'] = intval($row["{$prefix}_width"]);
- $vals['height'] = intval($row["{$prefix}_height"]);
- }
- if ($fld_url)
- $vals['url'] = $isCur ? $img->getURL() : $img->getArchiveUrl($row["oi_archive_name"]);
- if ($fld_comment)
- $vals['comment'] = $row["{$prefix}_description"];
-
- if ($fld_sha1)
- $vals['sha1'] = wfBaseConvert($row["{$prefix}_sha1"], 36, 16, 40);
-
- if ($fld_metadata) {
- $metadata = unserialize($row["{$prefix}_metadata"]);
- $vals['metadata'] = $metadata ? $metadata : null;
- $this->getResult()->setIndexedTagName_recursive($vals['metadata'], 'meta');
- }
-
- $data[] = $vals;
-
- if (!$history) // Stop after the first line.
- break;
-
- $isCur = false;
- }
-
- $img->resetHistory();
- }
-
- $this->getResult()->addValue(array ('query', 'pages', intval($pageId)),
- 'imagerepository',
- $repository);
- if (!empty($data))
- $this->addPageSubItems($pageId, $data);
- }
- }
- }
-
- protected function getAllowedParams() {
- return array (
- 'prop' => array (
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_DFLT => 'timestamp|user',
- ApiBase :: PARAM_TYPE => array (
- 'timestamp',
- 'user',
- 'comment',
- 'url',
- 'size',
- 'sha1',
- 'metadata'
- )
- ),
- 'history' => false,
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'prop' => 'What image information to get.',
- 'history' => 'Include upload history',
- );
- }
-
- protected function getDescription() {
- return array (
- 'Returns image information and upload history'
- );
- }
-
- protected function getExamples() {
- return array (
- 'api.php?action=query&titles=Image:Albert%20Einstein%20Head.jpg&prop=imageinfo',
- 'api.php?action=query&titles=Image:Test.jpg&prop=imageinfo&iihistory&iiprop=timestamp|user|url',
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryImageInfo.php 26855 2007-10-20 18:27:39Z catrope $';
- }
-}
+++ /dev/null
-<?php
-
-/*
- * Created on May 13, 2007
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ("ApiQueryBase.php");
-}
-
-/**
- * This query adds <images> subelement to all pages with the list of images embedded into those pages.
- *
- * @addtogroup API
- */
-class ApiQueryImages extends ApiQueryGeneratorBase {
-
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'im');
- }
-
- public function execute() {
- $this->run();
- }
-
- public function executeGenerator($resultPageSet) {
- $this->run($resultPageSet);
- }
-
- private function run($resultPageSet = null) {
-
- if ($this->getPageSet()->getGoodTitleCount() == 0)
- return; // nothing to do
-
- $this->addFields(array (
- 'il_from',
- 'il_to'
- ));
-
- $this->addTables('imagelinks');
- $this->addWhereFld('il_from', array_keys($this->getPageSet()->getGoodTitles()));
- $this->addOption('ORDER BY', "il_from, il_to");
-
- $db = $this->getDB();
- $res = $this->select(__METHOD__);
-
- if (is_null($resultPageSet)) {
-
- $data = array();
- $lastId = 0; // database has no ID 0
- while ($row = $db->fetchObject($res)) {
- if ($lastId != $row->il_from) {
- if($lastId != 0) {
- $this->addPageSubItems($lastId, $data);
- $data = array();
- }
- $lastId = $row->il_from;
- }
-
- $vals = array();
- ApiQueryBase :: addTitleInfo($vals, Title :: makeTitle(NS_IMAGE, $row->il_to));
- $data[] = $vals;
- }
-
- if($lastId != 0) {
- $this->addPageSubItems($lastId, $data);
- }
-
- } else {
-
- $titles = array();
- while ($row = $db->fetchObject($res)) {
- $titles[] = Title :: makeTitle(NS_IMAGE, $row->il_to);
- }
- $resultPageSet->populateFromTitles($titles);
- }
-
- $db->freeResult($res);
- }
-
- protected function getDescription() {
- return 'Returns all images contained on the given page(s)';
- }
-
- protected function getExamples() {
- return array (
- "Get a list of images used in the [[Main Page]]:",
- " api.php?action=query&prop=images&titles=Main%20Page",
- "Get information about all images used in the [[Main Page]]:",
- " api.php?action=query&generator=images&titles=Main%20Page&prop=info"
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryImages.php 24092 2007-07-14 19:04:31Z yurik $';
- }
-}
-
+++ /dev/null
-<?php
-
-/*
- * Created on Sep 25, 2006
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
-}
-
-/**
- * A query module to show basic page information.
- *
- * @addtogroup API
- */
-class ApiQueryInfo extends ApiQueryBase {
-
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'in');
- }
-
- public function requestExtraData($pageSet) {
- $pageSet->requestField('page_restrictions');
- $pageSet->requestField('page_is_redirect');
- $pageSet->requestField('page_is_new');
- $pageSet->requestField('page_counter');
- $pageSet->requestField('page_touched');
- $pageSet->requestField('page_latest');
- $pageSet->requestField('page_len');
- }
-
- public function execute() {
-
- global $wgUser;
-
- $params = $this->extractRequestParams();
- $fld_protection = false;
- if(!is_null($params['prop'])) {
- $prop = array_flip($params['prop']);
- $fld_protection = isset($prop['protection']);
- }
- if(!is_null($params['token'])) {
- $token = $params['token'];
- $tok_edit = $this->getTokenFlag($token, 'edit');
- $tok_delete = $this->getTokenFlag($token, 'delete');
- $tok_protect = $this->getTokenFlag($token, 'protect');
- $tok_move = $this->getTokenFlag($token, 'move');
- }
-
- $pageSet = $this->getPageSet();
- $titles = $pageSet->getGoodTitles();
- $result = $this->getResult();
-
- $pageRestrictions = $pageSet->getCustomField('page_restrictions');
- $pageIsRedir = $pageSet->getCustomField('page_is_redirect');
- $pageIsNew = $pageSet->getCustomField('page_is_new');
- $pageCounter = $pageSet->getCustomField('page_counter');
- $pageTouched = $pageSet->getCustomField('page_touched');
- $pageLatest = $pageSet->getCustomField('page_latest');
- $pageLength = $pageSet->getCustomField('page_len');
-
- if ($fld_protection && count($titles) > 0) {
- $this->addTables('page_restrictions');
- $this->addFields(array('pr_page', 'pr_type', 'pr_level', 'pr_expiry'));
- $this->addWhereFld('pr_page', array_keys($titles));
-
- $db = $this->getDB();
- $res = $this->select(__METHOD__);
- while($row = $db->fetchObject($res)) {
- $protections[$row->pr_page][] = array(
- 'type' => $row->pr_type,
- 'level' => $row->pr_level,
- 'expiry' => Block::decodeExpiry( $row->pr_expiry, TS_ISO_8601 )
- );
- }
- $db->freeResult($res);
- }
-
- foreach ( $titles as $pageid => $title ) {
- $pageInfo = array (
- 'touched' => wfTimestamp(TS_ISO_8601, $pageTouched[$pageid]),
- 'lastrevid' => intval($pageLatest[$pageid]),
- 'counter' => intval($pageCounter[$pageid]),
- 'length' => intval($pageLength[$pageid]),
- );
-
- if ($pageIsRedir[$pageid])
- $pageInfo['redirect'] = '';
-
- if ($pageIsNew[$pageid])
- $pageInfo['new'] = '';
-
- if (!is_null($token)) {
- // Currently all tokens are generated the same way, but it might change
- if ($tok_edit)
- $pageInfo['edittoken'] = $wgUser->editToken();
- if ($tok_delete)
- $pageInfo['deletetoken'] = $wgUser->editToken();
- if ($tok_protect)
- $pageInfo['protecttoken'] = $wgUser->editToken();
- if ($tok_move)
- $pageInfo['movetoken'] = $wgUser->editToken();
- }
-
- if($fld_protection) {
- if (isset($protections[$pageid])) {
- $pageInfo['protection'] = $protections[$pageid];
- $result->setIndexedTagName($pageInfo['protection'], 'pr');
- } else {
- # Also check old restrictions
- if( $pageRestrictions[$pageid] ) {
- foreach( explode( ':', trim( $pageRestrictions[$pageid] ) ) as $restrict ) {
- $temp = explode( '=', trim( $restrict ) );
- if(count($temp) == 1) {
- // old old format should be treated as edit/move restriction
- $restriction = trim( $temp[0] );
- $pageInfo['protection'][] = array(
- 'type' => 'edit',
- 'level' => $restriction,
- 'expiry' => 'infinity',
- );
- $pageInfo['protection'][] = array(
- 'type' => 'move',
- 'level' => $restriction,
- 'expiry' => 'infinity',
- );
- } else {
- $restriction = trim( $temp[1] );
- $pageInfo['protection'][] = array(
- 'type' => $temp[0],
- 'level' => $restriction,
- 'expiry' => 'infinity',
- );
- }
- }
- $result->setIndexedTagName($pageInfo['protection'], 'pr');
- } else {
- $pageInfo['protection'] = array();
- }
- }
- }
-
- $result->addValue(array (
- 'query',
- 'pages'
- ), $pageid, $pageInfo);
- }
-
- // Get edit tokens for missing titles if requested
- // Delete, protect and move tokens are N/A for missing titles anyway
- if($tok_edit)
- {
- $missing = $pageSet->getMissingTitles();
- $res = &$result->getData();
- foreach($missing as $pageid => $title)
- $res['query']['pages'][$pageid]['edittoken'] = $wgUser->editToken();
- }
- }
-
- protected function getAllowedParams() {
- return array (
- 'prop' => array (
- ApiBase :: PARAM_DFLT => NULL,
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_TYPE => array (
- 'protection'
- )),
- 'token' => array (
- ApiBase :: PARAM_DFLT => NULL,
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_TYPE => array (
- 'edit',
- 'delete',
- 'protect',
- 'move',
- )),
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'prop' => array (
- 'Which additional properties to get:',
- ' "protection" - List the protection level of each page'
- ),
- 'token' => 'Request a token to perform a data-modifying action on a page',
- );
- }
-
-
- protected function getDescription() {
- return 'Get basic page information such as namespace, title, last touched date, ...';
- }
-
- protected function getExamples() {
- return array (
- 'api.php?action=query&prop=info&titles=Main%20Page',
- 'api.php?action=query&prop=info&inprop=protection&titles=Main%20Page'
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryInfo.php 27877 2007-11-27 10:22:14Z rotem $';
- }
-}
-
+++ /dev/null
-<?php
-
-/*
- * Created on May 13, 2007
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ("ApiQueryBase.php");
-}
-
-/**
- * A query module to list all langlinks (links to correspanding foreign language pages).
- *
- * @addtogroup API
- */
-class ApiQueryLangLinks extends ApiQueryBase {
-
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'll');
- }
-
- public function execute() {
- $this->addFields(array (
- 'll_from',
- 'll_lang',
- 'll_title'
- ));
-
- $this->addTables('langlinks');
- $this->addWhereFld('ll_from', array_keys($this->getPageSet()->getGoodTitles()));
- $this->addOption('ORDER BY', "ll_from, ll_lang");
- $res = $this->select(__METHOD__);
-
- $data = array();
- $lastId = 0; // database has no ID 0
- $db = $this->getDB();
- while ($row = $db->fetchObject($res)) {
-
- if ($lastId != $row->ll_from) {
- if($lastId != 0) {
- $this->addPageSubItems($lastId, $data);
- $data = array();
- }
- $lastId = $row->ll_from;
- }
-
- $entry = array('lang'=>$row->ll_lang);
- ApiResult :: setContent($entry, $row->ll_title);
- $data[] = $entry;
- }
-
- if($lastId != 0) {
- $this->addPageSubItems($lastId, $data);
- }
-
- $db->freeResult($res);
- }
-
- protected function getDescription() {
- return 'Returns all interlanguage links from the given page(s)';
- }
-
- protected function getExamples() {
- return array (
- "Get interlanguage links from the [[Main Page]]:",
- " api.php?action=query&prop=langlinks&titles=Main%20Page&redirects",
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryLangLinks.php 23819 2007-07-07 03:05:09Z yurik $';
- }
-}
-
+++ /dev/null
-<?php
-
-/*
- * Created on May 12, 2007
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ("ApiQueryBase.php");
-}
-
-/**
- * A query module to list all wiki links on a given set of pages.
- *
- * @addtogroup API
- */
-class ApiQueryLinks extends ApiQueryGeneratorBase {
-
- const LINKS = 'links';
- const TEMPLATES = 'templates';
-
- private $table, $prefix, $description;
-
- public function __construct($query, $moduleName) {
-
- switch ($moduleName) {
- case self::LINKS :
- $this->table = 'pagelinks';
- $this->prefix = 'pl';
- $this->description = 'link';
- break;
- case self::TEMPLATES :
- $this->table = 'templatelinks';
- $this->prefix = 'tl';
- $this->description = 'template';
- break;
- default :
- ApiBase :: dieDebug(__METHOD__, 'Unknown module name');
- }
-
- parent :: __construct($query, $moduleName, $this->prefix);
- }
-
- public function execute() {
- $this->run();
- }
-
- public function executeGenerator($resultPageSet) {
- $this->run($resultPageSet);
- }
-
- private function run($resultPageSet = null) {
-
- if ($this->getPageSet()->getGoodTitleCount() == 0)
- return; // nothing to do
-
- $params = $this->extractRequestParams();
-
- $this->addFields(array (
- $this->prefix . '_from pl_from',
- $this->prefix . '_namespace pl_namespace',
- $this->prefix . '_title pl_title'
- ));
-
- $this->addTables($this->table);
- $this->addWhereFld($this->prefix . '_from', array_keys($this->getPageSet()->getGoodTitles()));
- $this->addWhereFld($this->prefix . '_namespace', $params['namespace']);
- $this->addOption('ORDER BY', str_replace('pl_', $this->prefix . '_', 'pl_from, pl_namespace, pl_title'));
-
- $db = $this->getDB();
- $res = $this->select(__METHOD__);
-
- if (is_null($resultPageSet)) {
-
- $data = array();
- $lastId = 0; // database has no ID 0
- while ($row = $db->fetchObject($res)) {
- if ($lastId != $row->pl_from) {
- if($lastId != 0) {
- $this->addPageSubItems($lastId, $data);
- $data = array();
- }
- $lastId = $row->pl_from;
- }
-
- $vals = array();
- ApiQueryBase :: addTitleInfo($vals, Title :: makeTitle($row->pl_namespace, $row->pl_title));
- $data[] = $vals;
- }
-
- if($lastId != 0) {
- $this->addPageSubItems($lastId, $data);
- }
-
- } else {
-
- $titles = array();
- while ($row = $db->fetchObject($res)) {
- $titles[] = Title :: makeTitle($row->pl_namespace, $row->pl_title);
- }
- $resultPageSet->populateFromTitles($titles);
- }
-
- $db->freeResult($res);
- }
-
- protected function getAllowedParams()
- {
- return array(
- 'namespace' => array(
- ApiBase :: PARAM_TYPE => 'namespace',
- ApiBase :: PARAM_ISMULTI => true
- )
- );
- }
-
- protected function getParamDescription()
- {
- return array(
- 'namespace' => "Show {$this->description}s in this namespace(s) only"
- );
- }
-
- protected function getDescription() {
- return "Returns all {$this->description}s from the given page(s)";
- }
-
- protected function getExamples() {
- return array (
- "Get {$this->description}s from the [[Main Page]]:",
- " api.php?action=query&prop={$this->getModuleName()}&titles=Main%20Page",
- "Get information about the {$this->description} pages in the [[Main Page]]:",
- " api.php?action=query&generator={$this->getModuleName()}&titles=Main%20Page&prop=info",
- "Get {$this->description}s from the Main Page in the User and Template namespaces:",
- " api.php?action=query&prop={$this->getModuleName()}&titles=Main%20Page&{$this->prefix}namespace=2|10"
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryLinks.php 24092 2007-07-14 19:04:31Z yurik $';
- }
-}
-
+++ /dev/null
-<?php
-
-/*
- * Created on Oct 16, 2006
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
-}
-
-/**
- * Query action to List the log events, with optional filtering by various parameters.
- *
- * @addtogroup API
- */
-class ApiQueryLogEvents extends ApiQueryBase {
-
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'le');
- }
-
- public function execute() {
- $params = $this->extractRequestParams();
- $db = $this->getDB();
-
- $prop = $params['prop'];
- $this->fld_ids = in_array('ids', $prop);
- $this->fld_title = in_array('title', $prop);
- $this->fld_type = in_array('type', $prop);
- $this->fld_user = in_array('user', $prop);
- $this->fld_timestamp = in_array('timestamp', $prop);
- $this->fld_comment = in_array('comment', $prop);
- $this->fld_details = in_array('details', $prop);
-
- list($tbl_logging, $tbl_page, $tbl_user) = $db->tableNamesN('logging', 'page', 'user');
-
- $this->addOption('STRAIGHT_JOIN');
- $this->addTables("$tbl_logging LEFT OUTER JOIN $tbl_page ON " .
- "log_namespace=page_namespace AND log_title=page_title " .
- "INNER JOIN $tbl_user ON user_id=log_user");
-
- $this->addFields(array (
- 'log_type',
- 'log_action',
- 'log_timestamp',
- ));
-
- // FIXME: Fake out log_id for now until the column is live on Wikimedia
- // $this->addFieldsIf('log_id', $this->fld_ids);
- $this->addFieldsIf('page_id', $this->fld_ids);
- $this->addFieldsIf('log_user', $this->fld_user);
- $this->addFieldsIf('user_name', $this->fld_user);
- $this->addFieldsIf('log_namespace', $this->fld_title);
- $this->addFieldsIf('log_title', $this->fld_title);
- $this->addFieldsIf('log_comment', $this->fld_comment);
- $this->addFieldsIf('log_params', $this->fld_details);
-
-
- $this->addWhereFld('log_deleted', 0);
- $this->addWhereFld('log_type', $params['type']);
- $this->addWhereRange('log_timestamp', $params['dir'], $params['start'], $params['end']);
-
- $limit = $params['limit'];
- $this->addOption('LIMIT', $limit +1);
-
- $user = $params['user'];
- if (!is_null($user)) {
- $userid = $db->selectField('user', 'user_id', array (
- 'user_name' => $user
- ));
- if (!$userid)
- $this->dieUsage("User name $user not found", 'param_user');
- $this->addWhereFld('log_user', $userid);
- }
-
- $title = $params['title'];
- if (!is_null($title)) {
- $titleObj = Title :: newFromText($title);
- if (is_null($titleObj))
- $this->dieUsage("Bad title value '$title'", 'param_title');
- $this->addWhereFld('log_namespace', $titleObj->getNamespace());
- $this->addWhereFld('log_title', $titleObj->getDBkey());
- }
-
- $data = array ();
- $count = 0;
- $res = $this->select(__METHOD__);
- while ($row = $db->fetchObject($res)) {
- if (++ $count > $limit) {
- // We've reached the one extra which shows that there are additional pages to be had. Stop here...
- $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->log_timestamp));
- break;
- }
-
- $vals = $this->extractRowInfo($row);
- if($vals)
- $data[] = $vals;
- }
- $db->freeResult($res);
-
- $this->getResult()->setIndexedTagName($data, 'item');
- $this->getResult()->addValue('query', $this->getModuleName(), $data);
- }
-
- private function extractRowInfo($row) {
- $vals = array();
-
- if ($this->fld_ids) {
- // FIXME: Fake out log_id for now until the column is live on Wikimedia
- // $vals['logid'] = intval($row->log_id);
- $vals['logid'] = 0;
- $vals['pageid'] = intval($row->page_id);
- }
-
- if ($this->fld_title) {
- $title = Title :: makeTitle($row->log_namespace, $row->log_title);
- ApiQueryBase :: addTitleInfo($vals, $title);
- }
-
- if ($this->fld_type) {
- $vals['type'] = $row->log_type;
- $vals['action'] = $row->log_action;
- }
-
- if ($this->fld_details && $row->log_params !== '') {
- $params = explode("\n", $row->log_params);
- switch ($row->log_type) {
- case 'move':
- if (isset ($params[0])) {
- $title = Title :: newFromText($params[0]);
- if ($title) {
- $vals2 = array();
- ApiQueryBase :: addTitleInfo($vals2, $title, "new_");
- $vals[$row->log_type] = $vals2;
- $params = null;
- }
- }
- break;
- case 'patrol':
- $vals2 = array();
- list( $vals2['cur'], $vals2['prev'], $vals2['auto'] ) = $params;
- $vals[$row->log_type] = $vals2;
- $params = null;
- break;
- case 'rights':
- $vals2 = array();
- list( $vals2['old'], $vals2['new'] ) = $params;
- $vals[$row->log_type] = $vals2;
- $params = null;
- break;
- case 'block':
- $vals2 = array();
- list( $vals2['duration'], $vals2['flags'] ) = $params;
- $vals[$row->log_type] = $vals2;
- $params = null;
- break;
- }
-
- if (isset($params)) {
- $this->getResult()->setIndexedTagName($params, 'param');
- $vals = array_merge($vals, $params);
- }
- }
-
- if ($this->fld_user) {
- $vals['user'] = $row->user_name;
- if(!$row->log_user)
- $vals['anon'] = '';
- }
- if ($this->fld_timestamp) {
- $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->log_timestamp);
- }
- if ($this->fld_comment && !empty ($row->log_comment)) {
- $vals['comment'] = $row->log_comment;
- }
-
- return $vals;
- }
-
-
- protected function getAllowedParams() {
- global $wgLogTypes;
- return array (
- 'prop' => array (
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_DFLT => 'ids|title|type|user|timestamp|comment|details',
- ApiBase :: PARAM_TYPE => array (
- 'ids',
- 'title',
- 'type',
- 'user',
- 'timestamp',
- 'comment',
- 'details',
- )
- ),
- 'type' => array (
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_TYPE => $wgLogTypes
- ),
- 'start' => array (
- ApiBase :: PARAM_TYPE => 'timestamp'
- ),
- 'end' => array (
- ApiBase :: PARAM_TYPE => 'timestamp'
- ),
- 'dir' => array (
- ApiBase :: PARAM_DFLT => 'older',
- ApiBase :: PARAM_TYPE => array (
- 'newer',
- 'older'
- )
- ),
- 'user' => null,
- 'title' => null,
- 'limit' => array (
- ApiBase :: PARAM_DFLT => 10,
- ApiBase :: PARAM_TYPE => 'limit',
- ApiBase :: PARAM_MIN => 1,
- ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
- ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
- )
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'type' => 'Filter log entries to only this type(s)',
- 'start' => 'The timestamp to start enumerating from.',
- 'end' => 'The timestamp to end enumerating.',
- 'dir' => 'In which direction to enumerate.',
- 'user' => 'Filter entries to those made by the given user.',
- 'title' => 'Filter entries to those related to a page.',
- 'limit' => 'How many total event entries to return.'
- );
- }
-
- protected function getDescription() {
- return 'Get events from logs.';
- }
-
- protected function getExamples() {
- return array (
- 'api.php?action=query&list=logevents'
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryLogEvents.php 24256 2007-07-18 21:47:09Z robchurch $';
- }
-}
-
+++ /dev/null
-<?php
-
-/*
- * Created on Oct 19, 2006
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
-}
-
-/**
- * A query action to enumerate the recent changes that were done to the wiki.
- * Various filters are supported.
- *
- * @addtogroup API
- */
-class ApiQueryRecentChanges extends ApiQueryBase {
-
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'rc');
- }
-
- private $fld_comment = false, $fld_user = false, $fld_flags = false,
- $fld_timestamp = false, $fld_title = false, $fld_ids = false,
- $fld_sizes = false;
-
- /**
- * Generates and outputs the result of this query based upon the provided parameters.
- */
- public function execute() {
- /* Initialize vars */
- $limit = $prop = $namespace = $show = $type = $dir = $start = $end = null;
-
- /* Get the parameters of the request. */
- extract($this->extractRequestParams());
-
- /* Build our basic query. Namely, something along the lines of:
- * SELECT * from recentchanges WHERE rc_timestamp > $start
- * AND rc_timestamp < $end AND rc_namespace = $namespace
- * AND rc_deleted = '0'
- */
- $this->addTables('recentchanges');
- $this->addWhereRange('rc_timestamp', $dir, $start, $end);
- $this->addWhereFld('rc_namespace', $namespace);
- $this->addWhereFld('rc_deleted', 0);
- if(!is_null($type))
- $this->addWhereFld('rc_type', $this->parseRCType($type));
-
- if (!is_null($show)) {
- $show = array_flip($show);
-
- /* Check for conflicting parameters. */
- if ((isset ($show['minor']) && isset ($show['!minor']))
- || (isset ($show['bot']) && isset ($show['!bot']))
- || (isset ($show['anon']) && isset ($show['!anon']))) {
-
- $this->dieUsage("Incorrect parameter - mutually exclusive values may not be supplied", 'show');
- }
-
- /* Add additional conditions to query depending upon parameters. */
- $this->addWhereIf('rc_minor = 0', isset ($show['!minor']));
- $this->addWhereIf('rc_minor != 0', isset ($show['minor']));
- $this->addWhereIf('rc_bot = 0', isset ($show['!bot']));
- $this->addWhereIf('rc_bot != 0', isset ($show['bot']));
- $this->addWhereIf('rc_user = 0', isset ($show['anon']));
- $this->addWhereIf('rc_user != 0', isset ($show['!anon']));
- }
-
- /* Add the fields we're concerned with to out query. */
- $this->addFields(array (
- 'rc_timestamp',
- 'rc_namespace',
- 'rc_title',
- 'rc_type',
- 'rc_moved_to_ns',
- 'rc_moved_to_title'
- ));
-
- /* Determine what properties we need to display. */
- if (!is_null($prop)) {
- $prop = array_flip($prop);
-
- /* Set up internal members based upon params. */
- $this->fld_comment = isset ($prop['comment']);
- $this->fld_user = isset ($prop['user']);
- $this->fld_flags = isset ($prop['flags']);
- $this->fld_timestamp = isset ($prop['timestamp']);
- $this->fld_title = isset ($prop['title']);
- $this->fld_ids = isset ($prop['ids']);
- $this->fld_sizes = isset ($prop['sizes']);
-
- /* Add fields to our query if they are specified as a needed parameter. */
- $this->addFieldsIf('rc_id', $this->fld_ids);
- $this->addFieldsIf('rc_cur_id', $this->fld_ids);
- $this->addFieldsIf('rc_this_oldid', $this->fld_ids);
- $this->addFieldsIf('rc_last_oldid', $this->fld_ids);
- $this->addFieldsIf('rc_comment', $this->fld_comment);
- $this->addFieldsIf('rc_user', $this->fld_user);
- $this->addFieldsIf('rc_user_text', $this->fld_user);
- $this->addFieldsIf('rc_minor', $this->fld_flags);
- $this->addFieldsIf('rc_bot', $this->fld_flags);
- $this->addFieldsIf('rc_new', $this->fld_flags);
- $this->addFieldsIf('rc_old_len', $this->fld_sizes);
- $this->addFieldsIf('rc_new_len', $this->fld_sizes);
- }
-
- /* Specify the limit for our query. It's $limit+1 because we (possibly) need to
- * generate a "continue" parameter, to allow paging. */
- $this->addOption('LIMIT', $limit +1);
-
- /* Specify the index to use in the query as rc_timestamp, instead of rc_revid (default). */
- $this->addOption('USE INDEX', 'rc_timestamp');
-
- $data = array ();
- $count = 0;
-
- /* Perform the actual query. */
- $db = $this->getDB();
- $res = $this->select(__METHOD__);
-
- /* Iterate through the rows, adding data extracted from them to our query result. */
- while ($row = $db->fetchObject($res)) {
- if (++ $count > $limit) {
- // We've reached the one extra which shows that there are additional pages to be had. Stop here...
- $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->rc_timestamp));
- break;
- }
-
- /* Extract the data from a single row. */
- $vals = $this->extractRowInfo($row);
-
- /* Add that row's data to our final output. */
- if($vals)
- $data[] = $vals;
- }
-
- $db->freeResult($res);
-
- /* Format the result */
- $result = $this->getResult();
- $result->setIndexedTagName($data, 'rc');
- $result->addValue('query', $this->getModuleName(), $data);
- }
-
- /**
- * Extracts from a single sql row the data needed to describe one recent change.
- *
- * @param $row The row from which to extract the data.
- * @return An array mapping strings (descriptors) to their respective string values.
- * @access private
- */
- private function extractRowInfo($row) {
- /* If page was moved somewhere, get the title of the move target. */
- $movedToTitle = false;
- if (!empty($row->rc_moved_to_title))
- $movedToTitle = Title :: makeTitle($row->rc_moved_to_ns, $row->rc_moved_to_title);
-
- /* Determine the title of the page that has been changed. */
- $title = Title :: makeTitle($row->rc_namespace, $row->rc_title);
-
- /* Our output data. */
- $vals = array ();
-
- $type = intval ( $row->rc_type );
-
- /* Determine what kind of change this was. */
- switch ( $type ) {
- case RC_EDIT: $vals['type'] = 'edit'; break;
- case RC_NEW: $vals['type'] = 'new'; break;
- case RC_MOVE: $vals['type'] = 'move'; break;
- case RC_LOG: $vals['type'] = 'log'; break;
- case RC_MOVE_OVER_REDIRECT: $vals['type'] = 'move over redirect'; break;
- default: $vals['type'] = $type;
- }
-
- /* Create a new entry in the result for the title. */
- if ($this->fld_title) {
- ApiQueryBase :: addTitleInfo($vals, $title);
- if ($movedToTitle)
- ApiQueryBase :: addTitleInfo($vals, $movedToTitle, "new_");
- }
-
- /* Add ids, such as rcid, pageid, revid, and oldid to the change's info. */
- if ($this->fld_ids) {
- $vals['rcid'] = intval($row->rc_id);
- $vals['pageid'] = intval($row->rc_cur_id);
- $vals['revid'] = intval($row->rc_this_oldid);
- $vals['old_revid'] = intval( $row->rc_last_oldid );
- }
-
- /* Add user data and 'anon' flag, if use is anonymous. */
- if ($this->fld_user) {
- $vals['user'] = $row->rc_user_text;
- if(!$row->rc_user)
- $vals['anon'] = '';
- }
-
- /* Add flags, such as new, minor, bot. */
- if ($this->fld_flags) {
- if ($row->rc_bot)
- $vals['bot'] = '';
- if ($row->rc_new)
- $vals['new'] = '';
- if ($row->rc_minor)
- $vals['minor'] = '';
- }
-
- /* Add sizes of each revision. (Only available on 1.10+) */
- if ($this->fld_sizes) {
- $vals['oldlen'] = intval($row->rc_old_len);
- $vals['newlen'] = intval($row->rc_new_len);
- }
-
- /* Add the timestamp. */
- if ($this->fld_timestamp)
- $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->rc_timestamp);
-
- /* Add edit summary / log summary. */
- if ($this->fld_comment && !empty ($row->rc_comment)) {
- $vals['comment'] = $row->rc_comment;
- }
-
- return $vals;
- }
-
- private function parseRCType($type)
- {
- if(is_array($type))
- {
- $retval = array();
- foreach($type as $t)
- $retval[] = $this->parseRCType($t);
- return $retval;
- }
- switch($type)
- {
- case 'edit': return RC_EDIT;
- case 'new': return RC_NEW;
- case 'log': return RC_LOG;
- }
- }
-
- protected function getAllowedParams() {
- return array (
- 'start' => array (
- ApiBase :: PARAM_TYPE => 'timestamp'
- ),
- 'end' => array (
- ApiBase :: PARAM_TYPE => 'timestamp'
- ),
- 'dir' => array (
- ApiBase :: PARAM_DFLT => 'older',
- ApiBase :: PARAM_TYPE => array (
- 'newer',
- 'older'
- )
- ),
- 'namespace' => array (
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_TYPE => 'namespace'
- ),
- 'prop' => array (
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_DFLT => 'title|timestamp|ids',
- ApiBase :: PARAM_TYPE => array (
- 'user',
- 'comment',
- 'flags',
- 'timestamp',
- 'title',
- 'ids',
- 'sizes'
- )
- ),
- 'show' => array (
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_TYPE => array (
- 'minor',
- '!minor',
- 'bot',
- '!bot',
- 'anon',
- '!anon'
- )
- ),
- 'limit' => array (
- ApiBase :: PARAM_DFLT => 10,
- ApiBase :: PARAM_TYPE => 'limit',
- ApiBase :: PARAM_MIN => 1,
- ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
- ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
- ),
- 'type' => array (
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_TYPE => array (
- 'edit',
- 'new',
- 'log'
- )
- )
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'start' => 'The timestamp to start enumerating from.',
- 'end' => 'The timestamp to end enumerating.',
- 'dir' => 'In which direction to enumerate.',
- 'namespace' => 'Filter log entries to only this namespace(s)',
- 'prop' => 'Include additional pieces of information',
- 'show' => array (
- 'Show only items that meet this criteria.',
- 'For example, to see only minor edits done by logged-in users, set show=minor|!anon'
- ),
- 'type' => 'Which types of changes to show.',
- 'limit' => 'How many total pages to return.'
- );
- }
-
- protected function getDescription() {
- return 'Enumerate recent changes';
- }
-
- protected function getExamples() {
- return array (
- 'api.php?action=query&list=recentchanges'
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryRecentChanges.php 26633 2007-10-12 14:03:43Z catrope $';
- }
-}
-
+++ /dev/null
-<?php
-
-/*
- * Created on Sep 7, 2006
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
-}
-
-/**
- * A query action to enumerate revisions of a given page, or show top revisions of multiple pages.
- * Various pieces of information may be shown - flags, comments, and the actual wiki markup of the rev.
- * In the enumeration mode, ranges of revisions may be requested and filtered.
- *
- * @addtogroup API
- */
-class ApiQueryRevisions extends ApiQueryBase {
-
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'rv');
- }
-
- private $fld_ids = false, $fld_flags = false, $fld_timestamp = false, $fld_size = false,
- $fld_comment = false, $fld_user = false, $fld_content = false;
-
- public function execute() {
- $limit = $startid = $endid = $start = $end = $dir = $prop = $user = $excludeuser = $token = null;
- extract($this->extractRequestParams());
-
- // If any of those parameters are used, work in 'enumeration' mode.
- // Enum mode can only be used when exactly one page is provided.
- // Enumerating revisions on multiple pages make it extremely
- // difficult to manage continuations and require additional SQL indexes
- $enumRevMode = (!is_null($user) || !is_null($excludeuser) || !is_null($limit) || !is_null($startid) || !is_null($endid) || $dir === 'newer' || !is_null($start) || !is_null($end));
-
-
- $pageSet = $this->getPageSet();
- $pageCount = $pageSet->getGoodTitleCount();
- $revCount = $pageSet->getRevisionCount();
-
- // Optimization -- nothing to do
- if ($revCount === 0 && $pageCount === 0)
- return;
-
- if ($revCount > 0 && $enumRevMode)
- $this->dieUsage('The revids= parameter may not be used with the list options (limit, startid, endid, dirNewer, start, end).', 'revids');
-
- if ($pageCount > 1 && $enumRevMode)
- $this->dieUsage('titles, pageids or a generator was used to supply multiple pages, but the limit, startid, endid, dirNewer, user, excludeuser, start and end parameters may only be used on a single page.', 'multpages');
-
- $this->addTables('revision');
- $this->addWhere('rev_deleted=0');
-
- $prop = array_flip($prop);
-
- // These field are needed regardless of the client requesting them
- $this->addFields('rev_id');
- $this->addFields('rev_page');
-
- // Optional fields
- $this->fld_ids = isset ($prop['ids']);
- // $this->addFieldsIf('rev_text_id', $this->fld_ids); // should this be exposed?
- $this->fld_flags = $this->addFieldsIf('rev_minor_edit', isset ($prop['flags']));
- $this->fld_timestamp = $this->addFieldsIf('rev_timestamp', isset ($prop['timestamp']));
- $this->fld_comment = $this->addFieldsIf('rev_comment', isset ($prop['comment']));
- $this->fld_size = $this->addFieldsIf('rev_len', isset ($prop['size']));
- if(!is_null($token))
- {
- $this->tok_rollback = $this->getTokenFlag($token, 'rollback');
- }
-
- if (isset ($prop['user'])) {
- $this->addFields('rev_user');
- $this->addFields('rev_user_text');
- $this->fld_user = true;
- }
- else if($this->tok_rollback)
- $this->addFields('rev_user_text');
-
- if (isset ($prop['content'])) {
-
- // For each page we will request, the user must have read rights for that page
- foreach ($pageSet->getGoodTitles() as $title) {
- if( !$title->userCanRead() )
- $this->dieUsage(
- 'The current user is not allowed to read ' . $title->getPrefixedText(),
- 'accessdenied');
- }
-
- $this->addTables('text');
- $this->addWhere('rev_text_id=old_id');
- $this->addFields('old_id');
- $this->addFields('old_text');
- $this->addFields('old_flags');
-
- $this->fld_content = true;
-
- $this->expandTemplates = $expandtemplates;
- }
-
- $userMax = ( $this->fld_content ? ApiBase::LIMIT_SML1 : ApiBase::LIMIT_BIG1 );
- $botMax = ( $this->fld_content ? ApiBase::LIMIT_SML2 : ApiBase::LIMIT_BIG2 );
-
- if ($enumRevMode) {
-
- // This is mostly to prevent parameter errors (and optimize SQL?)
- if (!is_null($startid) && !is_null($start))
- $this->dieUsage('start and startid cannot be used together', 'badparams');
-
- if (!is_null($endid) && !is_null($end))
- $this->dieUsage('end and endid cannot be used together', 'badparams');
-
- if(!is_null($user) && !is_null( $excludeuser))
- $this->dieUsage('user and excludeuser cannot be used together', 'badparams');
-
- // This code makes an assumption that sorting by rev_id and rev_timestamp produces
- // the same result. This way users may request revisions starting at a given time,
- // but to page through results use the rev_id returned after each page.
- // Switching to rev_id removes the potential problem of having more than
- // one row with the same timestamp for the same page.
- // The order needs to be the same as start parameter to avoid SQL filesort.
-
- if (is_null($startid) && is_null($endid))
- $this->addWhereRange('rev_timestamp', $dir, $start, $end);
- else
- $this->addWhereRange('rev_id', $dir, $startid, $endid);
-
- // must manually initialize unset limit
- if (is_null($limit))
- $limit = 10;
- $this->validateLimit('limit', $limit, 1, $userMax, $botMax);
-
- // There is only one ID, use it
- $this->addWhereFld('rev_page', current(array_keys($pageSet->getGoodTitles())));
-
- if(!is_null($user)) {
- $this->addWhereFld('rev_user_text', $user);
- } elseif (!is_null( $excludeuser)) {
- $this->addWhere('rev_user_text != ' . $this->getDB()->addQuotes($excludeuser));
- }
- }
- elseif ($revCount > 0) {
- $this->validateLimit('rev_count', $revCount, 1, $userMax, $botMax);
-
- // Get all revision IDs
- $this->addWhereFld('rev_id', array_keys($pageSet->getRevisionIDs()));
-
- // assumption testing -- we should never get more then $revCount rows.
- $limit = $revCount;
- }
- elseif ($pageCount > 0) {
- // When working in multi-page non-enumeration mode,
- // limit to the latest revision only
- $this->addTables('page');
- $this->addWhere('page_id=rev_page');
- $this->addWhere('page_latest=rev_id');
- $this->validateLimit('page_count', $pageCount, 1, $userMax, $botMax);
-
- // Get all page IDs
- $this->addWhereFld('page_id', array_keys($pageSet->getGoodTitles()));
-
- // assumption testing -- we should never get more then $pageCount rows.
- $limit = $pageCount;
- } else
- ApiBase :: dieDebug(__METHOD__, 'param validation?');
-
- $this->addOption('LIMIT', $limit +1);
-
- $data = array ();
- $count = 0;
- $res = $this->select(__METHOD__);
-
- $db = $this->getDB();
- while ($row = $db->fetchObject($res)) {
-
- if (++ $count > $limit) {
- // We've reached the one extra which shows that there are additional pages to be had. Stop here...
- if (!$enumRevMode)
- ApiBase :: dieDebug(__METHOD__, 'Got more rows then expected'); // bug report
- $this->setContinueEnumParameter('startid', intval($row->rev_id));
- break;
- }
-
- $this->getResult()->addValue(
- array (
- 'query',
- 'pages',
- intval($row->rev_page),
- 'revisions'),
- null,
- $this->extractRowInfo($row));
- }
- $db->freeResult($res);
-
- // Ensure that all revisions are shown as '<rev>' elements
- $result = $this->getResult();
- if ($result->getIsRawMode()) {
- $data =& $result->getData();
- foreach ($data['query']['pages'] as & $page) {
- if (is_array($page) && array_key_exists('revisions', $page)) {
- $result->setIndexedTagName($page['revisions'], 'rev');
- }
- }
- }
- }
-
- private function extractRowInfo($row) {
-
- $vals = array ();
-
- if ($this->fld_ids) {
- $vals['revid'] = intval($row->rev_id);
- // $vals['oldid'] = intval($row->rev_text_id); // todo: should this be exposed?
- }
-
- if ($this->fld_flags && $row->rev_minor_edit)
- $vals['minor'] = '';
-
- if ($this->fld_user) {
- $vals['user'] = $row->rev_user_text;
- if (!$row->rev_user)
- $vals['anon'] = '';
- }
-
- if ($this->fld_timestamp) {
- $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->rev_timestamp);
- }
-
- if ($this->fld_size && !is_null($row->rev_len)) {
- $vals['size'] = intval($row->rev_len);
- }
-
- if ($this->fld_comment && !empty ($row->rev_comment)) {
- $vals['comment'] = $row->rev_comment;
- }
-
- if($this->tok_rollback || ($this->fld_content && $this->expandTemplates))
- $title = Title::newFromID($row->rev_page);
-
- if($this->tok_rollback) {
- global $wgUser;
- $vals['rollbacktoken'] = $wgUser->editToken(array($title->getPrefixedText(), $row->rev_user_text));
- }
-
-
- if ($this->fld_content) {
- $text = Revision :: getRevisionText($row);
- if ($this->expandTemplates) {
- global $wgParser;
- $text = $wgParser->preprocess( $text, $title, new ParserOptions() );
- }
- ApiResult :: setContent($vals, $text);
- }
- return $vals;
- }
-
- protected function getAllowedParams() {
- return array (
- 'prop' => array (
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_DFLT => 'ids|timestamp|flags|comment|user',
- ApiBase :: PARAM_TYPE => array (
- 'ids',
- 'flags',
- 'timestamp',
- 'user',
- 'size',
- 'comment',
- 'content',
- )
- ),
- 'limit' => array (
- ApiBase :: PARAM_TYPE => 'limit',
- ApiBase :: PARAM_MIN => 1,
- ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
- ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
- ),
- 'startid' => array (
- ApiBase :: PARAM_TYPE => 'integer'
- ),
- 'endid' => array (
- ApiBase :: PARAM_TYPE => 'integer'
- ),
- 'start' => array (
- ApiBase :: PARAM_TYPE => 'timestamp'
- ),
- 'end' => array (
- ApiBase :: PARAM_TYPE => 'timestamp'
- ),
- 'dir' => array (
- ApiBase :: PARAM_DFLT => 'older',
- ApiBase :: PARAM_TYPE => array (
- 'newer',
- 'older'
- )
- ),
- 'user' => array(
- ApiBase :: PARAM_TYPE => 'user'
- ),
- 'excludeuser' => array(
- ApiBase :: PARAM_TYPE => 'user'
- ),
-
- 'expandtemplates' => false,
- 'token' => array(
- ApiBase :: PARAM_TYPE => array(
- 'rollback'
- ),
- ApiBase :: PARAM_ISMULTI => true
- ),
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'prop' => 'Which properties to get for each revision.',
- 'limit' => 'limit how many revisions will be returned (enum)',
- 'startid' => 'from which revision id to start enumeration (enum)',
- 'endid' => 'stop revision enumeration on this revid (enum)',
- 'start' => 'from which revision timestamp to start enumeration (enum)',
- 'end' => 'enumerate up to this timestamp (enum)',
- 'dir' => 'direction of enumeration - towards "newer" or "older" revisions (enum)',
- 'user' => 'only include revisions made by user',
- 'excludeuser' => 'exclude revisions made by user',
- 'expandtemplates' => 'expand templates in revision content',
- 'token' => 'Which tokens to obtain for each revision',
- );
- }
-
- protected function getDescription() {
- return array (
- 'Get revision information.',
- 'This module may be used in several ways:',
- ' 1) Get data about a set of pages (last revision), by setting titles or pageids parameter.',
- ' 2) Get revisions for one given page, by using titles/pageids with start/end/limit params.',
- ' 3) Get data about a set of revisions by setting their IDs with revids parameter.',
- 'All parameters marked as (enum) may only be used with a single page (#2).'
- );
- }
-
- protected function getExamples() {
- return array (
- 'Get data with content for the last revision of titles "API" and "Main Page":',
- ' api.php?action=query&prop=revisions&titles=API|Main%20Page&rvprop=timestamp|user|comment|content',
- 'Get last 5 revisions of the "Main Page":',
- ' api.php?action=query&prop=revisions&titles=Main%20Page&rvlimit=5&rvprop=timestamp|user|comment',
- 'Get first 5 revisions of the "Main Page":',
- ' api.php?action=query&prop=revisions&titles=Main%20Page&rvlimit=5&rvprop=timestamp|user|comment&rvdir=newer',
- 'Get first 5 revisions of the "Main Page" made after 2006-05-01:',
- ' api.php?action=query&prop=revisions&titles=Main%20Page&rvlimit=5&rvprop=timestamp|user|comment&rvdir=newer&rvstart=20060501000000',
- 'Get first 5 revisions of the "Main Page" that were not made made by anonymous user "127.0.0.1"',
- ' api.php?action=query&prop=revisions&titles=Main%20Page&rvlimit=5&rvprop=timestamp|user|comment&rvexcludeuser=127.0.0.1',
- 'Get first 5 revisions of the "Main Page" that were made by the user "MediaWiki default"',
- ' api.php?action=query&prop=revisions&titles=Main%20Page&rvlimit=5&rvprop=timestamp|user|comment&rvuser=MediaWiki%20default',
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryRevisions.php 28176 2007-12-05 06:32:17Z amidaniel $';
- }
-}
-
+++ /dev/null
-<?php
-
-/*
- * Created on July 30, 2007
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2007 Yuri Astrakhan <Firstname><Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
-}
-
-/**
- * Query module to perform full text search within wiki titles and content
- *
- * @addtogroup API
- */
-class ApiQuerySearch extends ApiQueryGeneratorBase {
-
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'sr');
- }
-
- public function execute() {
- $this->run();
- }
-
- public function executeGenerator($resultPageSet) {
- $this->run($resultPageSet);
- }
-
- private function run($resultPageSet = null) {
-
- $params = $this->extractRequestParams();
-
- $limit = $params['limit'];
- $query = $params['search'];
- if (is_null($query) || empty($query))
- $this->dieUsage("empty search string is not allowed", 'param-search');
-
- $search = SearchEngine::create();
- $search->setLimitOffset( $limit+1, $params['offset'] );
- $search->setNamespaces( $params['namespace'] );
- $search->showRedirects = $params['redirects'];
-
- if ($params['what'] == 'text')
- $matches = $search->searchText( $query );
- else
- $matches = $search->searchTitle( $query );
-
- $data = array ();
- $count = 0;
- while( $result = $matches->next() ) {
- if (++ $count > $limit) {
- // We've reached the one extra which shows that there are additional items to be had. Stop here...
- $this->setContinueEnumParameter('offset', $params['offset'] + $params['limit']);
- break;
- }
-
- $title = $result->getTitle();
- if (is_null($resultPageSet)) {
- $data[] = array(
- 'ns' => intval($title->getNamespace()),
- 'title' => $title->getPrefixedText());
- } else {
- $data[] = $title;
- }
- }
-
- if (is_null($resultPageSet)) {
- $result = $this->getResult();
- $result->setIndexedTagName($data, 'p');
- $result->addValue('query', $this->getModuleName(), $data);
- } else {
- $resultPageSet->populateFromTitles($data);
- }
- }
-
- protected function getAllowedParams() {
- return array (
- 'search' => null,
- 'namespace' => array (
- ApiBase :: PARAM_DFLT => 0,
- ApiBase :: PARAM_TYPE => 'namespace',
- ApiBase :: PARAM_ISMULTI => true,
- ),
- 'what' => array (
- ApiBase :: PARAM_DFLT => 'title',
- ApiBase :: PARAM_TYPE => array (
- 'title',
- 'text',
- )
- ),
- 'redirects' => false,
- 'offset' => 0,
- 'limit' => array (
- ApiBase :: PARAM_DFLT => 10,
- ApiBase :: PARAM_TYPE => 'limit',
- ApiBase :: PARAM_MIN => 1,
- ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
- ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
- )
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'search' => 'Search for all page titles (or content) that has this value.',
- 'namespace' => 'The namespace(s) to enumerate.',
- 'what' => 'Search inside the text or titles.',
- 'redirects' => 'Include redirect pages in the search.',
- 'offset' => 'Use this value to continue paging (return by query)',
- 'limit' => 'How many total pages to return.'
- );
- }
-
- protected function getDescription() {
- return 'Perform a full text search';
- }
-
- protected function getExamples() {
- return array (
- 'api.php?action=query&list=search&srsearch=meaning',
- 'api.php?action=query&list=search&srwhat=text&srsearch=meaning',
- 'api.php?action=query&generator=search&gsrsearch=meaning&prop=info',
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiQuerySearch.php 24453 2007-07-30 08:09:15Z yurik $';
- }
-}
-
+++ /dev/null
-<?php
-
-/*
- * Created on Sep 25, 2006
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
-}
-
-/**
- * A query action to return meta information about the wiki site.
- *
- * @addtogroup API
- */
-class ApiQuerySiteinfo extends ApiQueryBase {
-
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'si');
- }
-
- public function execute() {
-
- $params = $this->extractRequestParams();
-
- foreach ($params['prop'] as $p) {
- switch ($p) {
- default :
- ApiBase :: dieDebug(__METHOD__, "Unknown prop=$p");
- case 'general' :
- $this->appendGeneralInfo($p);
- break;
- case 'namespaces' :
- $this->appendNamespaces($p);
- break;
- case 'interwikimap' :
- $filteriw = isset($params['filteriw']) ? $params['filteriw'] : false;
- $this->appendInterwikiMap($p, $filteriw);
- break;
- case 'dbrepllag' :
- $this->appendDbReplLagInfo($p, $params['showalldb']);
- break;
- case 'statistics' :
- $this->appendStatistics($p);
- break;
- }
- }
- }
-
- protected function appendGeneralInfo($property) {
- global $wgSitename, $wgVersion, $wgCapitalLinks, $wgRightsCode, $wgRightsText, $wgLanguageCode, $IP;
-
- $data = array ();
- $mainPage = Title :: newFromText(wfMsgForContent('mainpage'));
- $data['mainpage'] = $mainPage->getText();
- $data['base'] = $mainPage->getFullUrl();
- $data['sitename'] = $wgSitename;
- $data['generator'] = "MediaWiki $wgVersion";
-
- $svn = SpecialVersion::getSvnRevision ( $IP );
- if ( $svn ) $data['rev'] = $svn;
-
- $data['case'] = $wgCapitalLinks ? 'first-letter' : 'case-sensitive'; // 'case-insensitive' option is reserved for future
- if (isset($wgRightsCode))
- $data['rightscode'] = $wgRightsCode;
- $data['rights'] = $wgRightsText;
- $data['lang'] = $wgLanguageCode;
-
- $this->getResult()->addValue('query', $property, $data);
- }
-
- protected function appendNamespaces($property) {
- global $wgContLang;
-
- $data = array ();
- foreach ($wgContLang->getFormattedNamespaces() as $ns => $title) {
- $data[$ns] = array (
- 'id' => $ns
- );
- ApiResult :: setContent($data[$ns], $title);
- }
-
- $this->getResult()->setIndexedTagName($data, 'ns');
- $this->getResult()->addValue('query', $property, $data);
- }
-
- protected function appendInterwikiMap($property, $filter) {
-
- $this->resetQueryParams();
- $this->addTables('interwiki');
- $this->addFields(array('iw_prefix', 'iw_local', 'iw_url'));
-
- if($filter === 'local') {
- $this->addWhere('iw_local = 1');
- } elseif($filter === '!local') {
- $this->addWhere('iw_local = 0');
- } elseif($filter !== false) {
- ApiBase :: dieDebug(__METHOD__, "Unknown filter=$filter");
- }
-
- $this->addOption('ORDER BY', 'iw_prefix');
-
- $db = $this->getDB();
- $res = $this->select(__METHOD__);
-
- $data = array();
- while($row = $db->fetchObject($res))
- {
- $val['prefix'] = $row->iw_prefix;
- if ($row->iw_local == '1')
- $val['local'] = '';
-// $val['trans'] = intval($row->iw_trans); // should this be exposed?
- $val['url'] = $row->iw_url;
-
- $data[] = $val;
- }
- $db->freeResult($res);
-
- $this->getResult()->setIndexedTagName($data, 'iw');
- $this->getResult()->addValue('query', $property, $data);
- }
-
- protected function appendDbReplLagInfo($property, $includeAll) {
- global $wgLoadBalancer, $wgShowHostnames;
-
- $data = array();
-
- if ($includeAll) {
- if (!$wgShowHostnames)
- $this->dieUsage('Cannot view all servers info unless $wgShowHostnames is true', 'includeAllDenied');
-
- global $wgDBservers;
- $lags = $wgLoadBalancer->getLagTimes();
- foreach( $lags as $i => $lag ) {
- $data[] = array (
- 'host' => $wgDBservers[$i]['host'],
- 'lag' => $lag);
- }
- } else {
- list( $host, $lag ) = $wgLoadBalancer->getMaxLag();
- $data[] = array (
- 'host' => $wgShowHostnames ? $host : '',
- 'lag' => $lag);
- }
-
- $result = $this->getResult();
- $result->setIndexedTagName($data, 'db');
- $result->addValue('query', $property, $data);
- }
-
- protected function appendStatistics($property) {
- $data = array ();
- $data['pages'] = intval(SiteStats::pages());
- $data['articles'] = intval(SiteStats::articles());
- $data['views'] = intval(SiteStats::views());
- $data['edits'] = intval(SiteStats::edits());
- $data['images'] = intval(SiteStats::images());
- $data['users'] = intval(SiteStats::users());
- $data['admins'] = intval(SiteStats::admins());
- $data['jobs'] = intval(SiteStats::jobs());
- $this->getResult()->addValue('query', $property, $data);
- }
-
- protected function getAllowedParams() {
- return array (
-
- 'prop' => array (
- ApiBase :: PARAM_DFLT => 'general',
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_TYPE => array (
- 'general',
- 'namespaces',
- 'interwikimap',
- 'dbrepllag',
- 'statistics',
- )),
-
- 'filteriw' => array (
- ApiBase :: PARAM_TYPE => array (
- 'local',
- '!local',
- )),
-
- 'showalldb' => false,
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'prop' => array (
- 'Which sysinfo properties to get:',
- ' "general" - Overall system information',
- ' "namespaces" - List of registered namespaces (localized)',
- ' "statistics" - Returns site statistics',
- ' "interwikimap" - Returns interwiki map (optionally filtered)',
- ' "dbrepllag" - Returns database server with the highest replication lag',
- ),
- 'filteriw' => 'Return only local or only nonlocal entries of the interwiki map',
- 'showalldb' => 'List all database servers, not just the one lagging the most',
- );
- }
-
- protected function getDescription() {
- return 'Return general information about the site.';
- }
-
- protected function getExamples() {
- return array(
- 'api.php?action=query&meta=siteinfo&siprop=general|namespaces|statistics',
- 'api.php?action=query&meta=siteinfo&siprop=interwikimap&sifilteriw=local',
- 'api.php?action=query&meta=siteinfo&siprop=dbrepllag&sishowalldb',
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiQuerySiteinfo.php 26444 2007-10-06 02:30:00Z amidaniel $';
- }
-}
+++ /dev/null
-<?php
-
-/*
- * Created on Oct 16, 2006
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
-}
-
-/**
- * This query action adds a list of a specified user's contributions to the output.
- *
- * @addtogroup API
- */
-class ApiQueryContributions extends ApiQueryBase {
-
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'uc');
- }
-
- private $params, $username;
- private $fld_ids = false, $fld_title = false, $fld_timestamp = false,
- $fld_comment = false, $fld_flags = false;
-
- public function execute() {
-
- // Parse some parameters
- $this->params = $this->extractRequestParams();
-
- $prop = array_flip($this->params['prop']);
- $this->fld_ids = isset($prop['ids']);
- $this->fld_title = isset($prop['title']);
- $this->fld_comment = isset($prop['comment']);
- $this->fld_flags = isset($prop['flags']);
- $this->fld_timestamp = isset($prop['timestamp']);
-
- // TODO: if the query is going only against the revision table, should this be done?
- $this->selectNamedDB('contributions', DB_SLAVE, 'contributions');
- $db = $this->getDB();
-
- // Prepare query
- $this->prepareUsername();
- $this->prepareQuery();
-
- //Do the actual query.
- $res = $this->select( __METHOD__ );
-
- //Initialise some variables
- $data = array ();
- $count = 0;
- $limit = $this->params['limit'];
-
- //Fetch each row
- while ( $row = $db->fetchObject( $res ) ) {
- if (++ $count > $limit) {
- // We've reached the one extra which shows that there are additional pages to be had. Stop here...
- $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->rev_timestamp));
- break;
- }
-
- $vals = $this->extractRowInfo($row);
- if ($vals)
- $data[] = $vals;
- }
-
- //Free the database record so the connection can get on with other stuff
- $db->freeResult($res);
-
- //And send the whole shebang out as output.
- $this->getResult()->setIndexedTagName($data, 'item');
- $this->getResult()->addValue('query', $this->getModuleName(), $data);
- }
-
- /**
- * Validate the 'user' parameter and set the value to compare
- * against `revision`.`rev_user_text`
- */
- private function prepareUsername() {
- $user = $this->params['user'];
- if( $user ) {
- $name = User::isIP( $user )
- ? $user
- : User::getCanonicalName( $user, 'valid' );
- if( $name === false ) {
- $this->dieUsage( "User name {$user} is not valid", 'param_user' );
- } else {
- $this->username = $name;
- }
- } else {
- $this->dieUsage( 'User parameter may not be empty', 'param_user' );
- }
- }
-
- /**
- * Prepares the query and returns the limit of rows requested
- */
- private function prepareQuery() {
-
- //We're after the revision table, and the corresponding page row for
- //anything we retrieve.
- list ($tbl_page, $tbl_revision) = $this->getDB()->tableNamesN('page', 'revision');
- $this->addTables("$tbl_revision LEFT OUTER JOIN $tbl_page ON page_id=rev_page");
-
- $this->addWhereFld('rev_deleted', 0);
-
- // We only want pages by the specified user.
- $this->addWhereFld( 'rev_user_text', $this->username );
-
- // ... and in the specified timeframe.
- $this->addWhereRange('rev_timestamp',
- $this->params['dir'], $this->params['start'], $this->params['end'] );
-
- $this->addWhereFld('page_namespace', $this->params['namespace']);
-
- $show = $this->params['show'];
- if (!is_null($show)) {
- $show = array_flip($show);
- if (isset ($show['minor']) && isset ($show['!minor']))
- $this->dieUsage("Incorrect parameter - mutually exclusive values may not be supplied", 'show');
-
- $this->addWhereIf('rev_minor_edit = 0', isset ($show['!minor']));
- $this->addWhereIf('rev_minor_edit != 0', isset ($show['minor']));
- }
-
- $this->addOption('LIMIT', $this->params['limit'] + 1);
-
- // Mandatory fields: timestamp allows request continuation
- // ns+title checks if the user has access rights for this page
- $this->addFields(array(
- 'rev_timestamp',
- 'page_namespace',
- 'page_title',
- ));
-
- $this->addFieldsIf('rev_page', $this->fld_ids);
- $this->addFieldsIf('rev_id', $this->fld_ids);
- // $this->addFieldsIf('rev_text_id', $this->fld_ids); // Should this field be exposed?
- $this->addFieldsIf('rev_comment', $this->fld_comment);
- $this->addFieldsIf('rev_minor_edit', $this->fld_flags);
-
- // These fields depend only work if the page table is joined
- $this->addFieldsIf('page_is_new', $this->fld_flags);
- }
-
- /**
- * Extract fields from the database row and append them to a result array
- */
- private function extractRowInfo($row) {
-
- $vals = array();
-
- if ($this->fld_ids) {
- $vals['pageid'] = intval($row->rev_page);
- $vals['revid'] = intval($row->rev_id);
- // $vals['textid'] = intval($row->rev_text_id); // todo: Should this field be exposed?
- }
-
- if ($this->fld_title)
- ApiQueryBase :: addTitleInfo($vals,
- Title :: makeTitle($row->page_namespace, $row->page_title));
-
- if ($this->fld_timestamp)
- $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->rev_timestamp);
-
- if ($this->fld_flags) {
- if ($row->page_is_new)
- $vals['new'] = '';
- if ($row->rev_minor_edit)
- $vals['minor'] = '';
- }
-
- if ($this->fld_comment && !empty ($row->rev_comment))
- $vals['comment'] = $row->rev_comment;
-
- return $vals;
- }
-
- protected function getAllowedParams() {
- return array (
- 'limit' => array (
- ApiBase :: PARAM_DFLT => 10,
- ApiBase :: PARAM_TYPE => 'limit',
- ApiBase :: PARAM_MIN => 1,
- ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
- ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
- ),
- 'start' => array (
- ApiBase :: PARAM_TYPE => 'timestamp'
- ),
- 'end' => array (
- ApiBase :: PARAM_TYPE => 'timestamp'
- ),
- 'user' => array (
- ApiBase :: PARAM_TYPE => 'user'
- ),
- 'dir' => array (
- ApiBase :: PARAM_DFLT => 'older',
- ApiBase :: PARAM_TYPE => array (
- 'newer',
- 'older'
- )
- ),
- 'namespace' => array (
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_TYPE => 'namespace'
- ),
- 'prop' => array (
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_DFLT => 'ids|title|timestamp|flags|comment',
- ApiBase :: PARAM_TYPE => array (
- 'ids',
- 'title',
- 'timestamp',
- 'comment',
- 'flags'
- )
- ),
- 'show' => array (
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_TYPE => array (
- 'minor',
- '!minor',
- )
- ),
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'limit' => 'The maximum number of contributions to return.',
- 'start' => 'The start timestamp to return from.',
- 'end' => 'The end timestamp to return to.',
- 'user' => 'The user to retrieve contributions for.',
- 'dir' => 'The direction to search (older or newer).',
- 'namespace' => 'Only list contributions in these namespaces',
- 'prop' => 'Include additional pieces of information',
- 'show' => 'Show only items that meet this criteria, e.g. non minor edits only: show=!minor',
- );
- }
-
- protected function getDescription() {
- return 'Get all edits by a user';
- }
-
- protected function getExamples() {
- return array (
- 'api.php?action=query&list=usercontribs&ucuser=YurikBot'
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryUserContributions.php 24754 2007-08-13 18:18:18Z robchurch $';
- }
-}
-
+++ /dev/null
-<?php
-
-/*
- * Created on July 30, 2007
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2007 Yuri Astrakhan <Firstname><Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
-}
-
-/**
- * Query module to get information about the currently logged-in user
- *
- * @addtogroup API
- */
-class ApiQueryUserInfo extends ApiQueryBase {
-
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'ui');
- }
-
- public function execute() {
-
- global $wgUser;
-
- $params = $this->extractRequestParams();
- $result = $this->getResult();
-
- $vals = array();
- $vals['name'] = $wgUser->getName();
-
- if( $wgUser->isAnon() ) $vals['anon'] = '';
-
- if (!is_null($params['prop'])) {
- $prop = array_flip($params['prop']);
- if (isset($prop['blockinfo'])) {
- if ($wgUser->isBlocked()) {
- $vals['blockedby'] = User::whoIs($wgUser->blockedBy());
- $vals['blockreason'] = $wgUser->blockedFor();
- }
- }
- if (isset($prop['hasmsg']) && $wgUser->getNewtalk()) {
- $vals['messages'] = '';
- }
- if (isset($prop['groups'])) {
- $vals['groups'] = $wgUser->getGroups();
- $result->setIndexedTagName($vals['groups'], 'g'); // even if empty
- }
- if (isset($prop['rights'])) {
- $vals['rights'] = $wgUser->getRights();
- $result->setIndexedTagName($vals['rights'], 'r'); // even if empty
- }
- if (isset($prop['options'])) {
- $vals['options'] = (is_null($wgUser->mOptions) ? User::getDefaultOptions() : $wgUser->mOptions);
- }
- }
-
- $result->addValue(null, $this->getModuleName(), $vals);
- }
-
- protected function getAllowedParams() {
- return array (
- 'prop' => array (
- ApiBase :: PARAM_DFLT => NULL,
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_TYPE => array (
- 'blockinfo',
- 'hasmsg',
- 'groups',
- 'rights',
- 'options'
- ))
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'prop' => array(
- 'What pieces of information to include',
- ' blockinfo - tags if the user is blocked, by whom, and for what reason',
- ' hasmsg - adds a tag "message" if user has pending messages',
- ' groups - lists all the groups the current user belongs to',
- ' rights - lists of all rights the current user has',
- ' options - lists all preferences the current user has set'
- )
- );
- }
-
- protected function getDescription() {
- return 'Get information about the current user';
- }
-
- protected function getExamples() {
- return array (
- 'api.php?action=query&meta=userinfo',
- 'api.php?action=query&meta=userinfo&uiprop=blockinfo|groups|rights|hasmsg',
- 'api.php?action=query&meta=userinfo&uioption=rememberpassword',
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryUserInfo.php 27153 2007-11-03 16:08:43Z catrope $';
- }
-}
-
+++ /dev/null
-<?php
-
-/*
- * Created on Sep 25, 2006
- *
- * API for MediaWiki 1.8+
- *
- * Copyright (C) 2006 Yuri Astrakhan <Firstname><Lastname>@gmail.com
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-if (!defined('MEDIAWIKI')) {
- // Eclipse helper - will be ignored in production
- require_once ('ApiQueryBase.php');
-}
-
-/**
- * This query action allows clients to retrieve a list of recently modified pages
- * that are part of the logged-in user's watchlist.
- *
- * @addtogroup API
- */
-class ApiQueryWatchlist extends ApiQueryGeneratorBase {
-
- public function __construct($query, $moduleName) {
- parent :: __construct($query, $moduleName, 'wl');
- }
-
- public function execute() {
- $this->run();
- }
-
- public function executeGenerator($resultPageSet) {
- $this->run($resultPageSet);
- }
-
- private $fld_ids = false, $fld_title = false, $fld_patrol = false, $fld_flags = false,
- $fld_timestamp = false, $fld_user = false, $fld_comment = false, $fld_sizes = false;
-
- private function run($resultPageSet = null) {
- global $wgUser, $wgDBtype;
-
- $this->selectNamedDB('watchlist', DB_SLAVE, 'watchlist');
-
- if (!$wgUser->isLoggedIn())
- $this->dieUsage('You must be logged-in to have a watchlist', 'notloggedin');
-
- $allrev = $start = $end = $namespace = $dir = $limit = $prop = null;
- extract($this->extractRequestParams());
-
- if (!is_null($prop) && is_null($resultPageSet)) {
-
- $prop = array_flip($prop);
-
- $this->fld_ids = isset($prop['ids']);
- $this->fld_title = isset($prop['title']);
- $this->fld_flags = isset($prop['flags']);
- $this->fld_user = isset($prop['user']);
- $this->fld_comment = isset($prop['comment']);
- $this->fld_timestamp = isset($prop['timestamp']);
- $this->fld_sizes = isset($prop['sizes']);
- $this->fld_patrol = isset($prop['patrol']);
-
- if ($this->fld_patrol) {
- global $wgUseRCPatrol, $wgUser;
- if (!$wgUseRCPatrol || !$wgUser->isAllowed('patrol'))
- $this->dieUsage('patrol property is not available', 'patrol');
- }
- }
-
- if (is_null($resultPageSet)) {
- $this->addFields(array (
- 'rc_cur_id',
- 'rc_this_oldid',
- 'rc_namespace',
- 'rc_title',
- 'rc_timestamp'
- ));
-
- $this->addFieldsIf('rc_new', $this->fld_flags);
- $this->addFieldsIf('rc_minor', $this->fld_flags);
- $this->addFieldsIf('rc_user', $this->fld_user);
- $this->addFieldsIf('rc_user_text', $this->fld_user);
- $this->addFieldsIf('rc_comment', $this->fld_comment);
- $this->addFieldsIf('rc_patrolled', $this->fld_patrol);
- $this->addFieldsIf('rc_old_len', $this->fld_sizes);
- $this->addFieldsIf('rc_new_len', $this->fld_sizes);
- }
- elseif ($allrev) {
- $this->addFields(array (
- 'rc_this_oldid',
- 'rc_namespace',
- 'rc_title',
- 'rc_timestamp'
- ));
- } else {
- $this->addFields(array (
- 'rc_cur_id',
- 'rc_namespace',
- 'rc_title',
- 'rc_timestamp'
- ));
- }
-
- $this->addTables(array (
- 'watchlist',
- 'page',
- 'recentchanges'
- ));
-
- $userId = $wgUser->getID();
- $this->addWhere(array (
- 'wl_namespace = rc_namespace',
- 'wl_title = rc_title',
- 'rc_cur_id = page_id',
- 'wl_user' => $userId,
- 'rc_deleted' => 0,
- ));
-
- $this->addWhereRange('rc_timestamp', $dir, $start, $end);
- $this->addWhereFld('wl_namespace', $namespace);
- $this->addWhereIf('rc_this_oldid=page_latest', !$allrev);
-
- # This is a index optimization for mysql, as done in the Special:Watchlist page
- $this->addWhereIf("rc_timestamp > ''", !isset ($start) && !isset ($end) && $wgDBtype == 'mysql');
-
- $this->addOption('LIMIT', $limit +1);
-
- $data = array ();
- $count = 0;
- $res = $this->select(__METHOD__);
-
- $db = $this->getDB();
- while ($row = $db->fetchObject($res)) {
- if (++ $count > $limit) {
- // We've reached the one extra which shows that there are additional pages to be had. Stop here...
- $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->rc_timestamp));
- break;
- }
-
- if (is_null($resultPageSet)) {
- $vals = $this->extractRowInfo($row);
- if ($vals)
- $data[] = $vals;
- } else {
- if ($allrev) {
- $data[] = intval($row->rc_this_oldid);
- } else {
- $data[] = intval($row->rc_cur_id);
- }
- }
- }
-
- $db->freeResult($res);
-
- if (is_null($resultPageSet)) {
- $this->getResult()->setIndexedTagName($data, 'item');
- $this->getResult()->addValue('query', $this->getModuleName(), $data);
- }
- elseif ($allrev) {
- $resultPageSet->populateFromRevisionIDs($data);
- } else {
- $resultPageSet->populateFromPageIDs($data);
- }
- }
-
- private function extractRowInfo($row) {
-
- $vals = array ();
-
- if ($this->fld_ids) {
- $vals['pageid'] = intval($row->rc_cur_id);
- $vals['revid'] = intval($row->rc_this_oldid);
- }
-
- if ($this->fld_title)
- ApiQueryBase :: addTitleInfo($vals, Title :: makeTitle($row->rc_namespace, $row->rc_title));
-
- if ($this->fld_user) {
- $vals['user'] = $row->rc_user_text;
- if (!$row->rc_user)
- $vals['anon'] = '';
- }
-
- if ($this->fld_flags) {
- if ($row->rc_new)
- $vals['new'] = '';
- if ($row->rc_minor)
- $vals['minor'] = '';
- }
-
- if ($this->fld_patrol && isset($row->rc_patrolled))
- $vals['patrolled'] = '';
-
- if ($this->fld_timestamp)
- $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->rc_timestamp);
-
- $this->addFieldsIf('rc_new_len', $this->fld_sizes);
-
- if ($this->fld_sizes) {
- $vals['oldlen'] = intval($row->rc_old_len);
- $vals['newlen'] = intval($row->rc_new_len);
- }
-
- if ($this->fld_comment && !empty ($row->rc_comment))
- $vals['comment'] = $row->rc_comment;
-
- return $vals;
- }
-
- protected function getAllowedParams() {
- return array (
- 'allrev' => false,
- 'start' => array (
- ApiBase :: PARAM_TYPE => 'timestamp'
- ),
- 'end' => array (
- ApiBase :: PARAM_TYPE => 'timestamp'
- ),
- 'namespace' => array (
- ApiBase :: PARAM_ISMULTI => true,
- ApiBase :: PARAM_TYPE => 'namespace'
- ),
- 'dir' => array (
- ApiBase :: PARAM_DFLT => 'older',
- ApiBase :: PARAM_TYPE => array (
- 'newer',
- 'older'
- )
- ),
- 'limit' => array (
- ApiBase :: PARAM_DFLT => 10,
- ApiBase :: PARAM_TYPE => 'limit',
- ApiBase :: PARAM_MIN => 1,
- ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
- ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
- ),
- 'prop' => array (
- APIBase :: PARAM_ISMULTI => true,
- APIBase :: PARAM_DFLT => 'ids|title|flags',
- APIBase :: PARAM_TYPE => array (
- 'ids',
- 'title',
- 'flags',
- 'user',
- 'comment',
- 'timestamp',
- 'patrol',
- 'sizes',
- )
- )
- );
- }
-
- protected function getParamDescription() {
- return array (
- 'allrev' => 'Include multiple revisions of the same page within given timeframe.',
- 'start' => 'The timestamp to start enumerating from.',
- 'end' => 'The timestamp to end enumerating.',
- 'namespace' => 'Filter changes to only the given namespace(s).',
- 'dir' => 'In which direction to enumerate pages.',
- 'limit' => 'How many total pages to return per request.',
- 'prop' => 'Which additional items to get (non-generator mode only).'
- );
- }
-
- protected function getDescription() {
- return '';
- }
-
- protected function getExamples() {
- return array (
- 'api.php?action=query&list=watchlist',
- 'api.php?action=query&list=watchlist&wlprop=ids|title|timestamp|user|comment',
- 'api.php?action=query&list=watchlist&wlallrev&wlprop=ids|title|timestamp|user|comment',
- 'api.php?action=query&generator=watchlist&prop=info',
- 'api.php?action=query&generator=watchlist&gwlallrev&prop=revisions&rvprop=timestamp|user'
- );
- }
-
- public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryWatchlist.php 24092 2007-07-14 19:04:31Z yurik $';
- }
-}
-