public function execute() { $prop = null; extract($this->extractRequestParams()); foreach ($prop as $p) { switch ($p) { case 'general': global $wgSitename, $wgVersion, $wgCapitalLinks; $data = array(); $mainPage = Title::newFromText(wfMsgForContent('mainpage')); $data['mainpage'] = $mainPage->getText(); $data['base'] = $mainPage->getFullUrl(); $data['sitename'] = $wgSitename; $data['generator'] = "MediaWiki {$wgVersion}"; $data['case'] = $wgCapitalLinks ? 'first-letter' : 'case-sensitive'; // 'case-insensitive' option is reserved for future $this->getResult()->addValue('query', $p, $data); break; case 'namespaces': global $wgContLang; $data = array(); foreach ($wgContLang->getFormattedNamespaces() as $ns => $title) { $data[$ns] = array('id' => $ns); ApiResult::setContent($data[$ns], $title); } ApiResult::setIndexedTagName($data, 'ns'); $this->getResult()->addValue('query', $p, $data); break; default: ApiBase::dieDebug(__METHOD__, "Unknown prop={$p}"); } } }
/** * Switch this module to generator mode. By default, generator mode is * switched off and the module acts like a normal query module. * @since 1.21 requires pageset parameter * @param ApiPageSet $generatorPageSet ApiPageSet object that the module will get * by calling getPageSet() when in generator mode. */ public function setGeneratorMode(ApiPageSet $generatorPageSet) { if ($generatorPageSet === null) { ApiBase::dieDebug(__METHOD__, 'Required parameter missing - $generatorPageSet'); } $this->mGeneratorPageSet = $generatorPageSet; }
public function execute() { global $wgUser; $this->checkPermission($wgUser); $params = $this->extractRequestParams(); $res = array(); $concurrencyCheck = new ConcurrencyCheck($params['resourcetype'], $wgUser); switch ($params['ccaction']) { case 'checkout': case 'checkin': if ($concurrencyCheck->{$params}['ccaction']($params['record'])) { $res['result'] = 'success'; } else { $res['result'] = 'failure'; } // data to be utilized by the caller for checkout if ($params['ccaction'] === 'checkout') { $lastCheckout = $concurrencyCheck->checkoutResult(); if ($res['result'] === 'success') { $user = $wgUser; } else { $user = User::newFromId(intval($lastCheckout['userId'])); } if (!$user->isAnon()) { $res['userid'] = $user->getId(); $res['username'] = $user->getName(); } $res['expiration'] = $lastCheckout['expiration']; } break; default: ApiBase::dieDebug(__METHOD__, "Unhandled concurrency action: {$params['ccaction']}"); } $this->getResult()->addValue(null, $this->getModuleName(), $res); }
public function __construct($query, $moduleName) { switch ($moduleName) { case 'alllinks': $prefix = 'al'; $this->table = 'pagelinks'; $this->tablePrefix = 'pl_'; $this->dfltNamespace = NS_MAIN; $this->indexTag = 'l'; $this->description = 'Enumerate all links that point to a given namespace'; $this->descriptionLink = 'link'; $this->descriptionLinked = 'linked'; $this->descriptionLinking = 'linking'; break; case 'alltransclusions': $prefix = 'at'; $this->table = 'templatelinks'; $this->tablePrefix = 'tl_'; $this->dfltNamespace = NS_TEMPLATE; $this->indexTag = 't'; $this->description = 'List all transclusions (pages embedded using {{x}}), including non-existing'; $this->descriptionLink = 'transclusion'; $this->descriptionLinked = 'transcluded'; $this->descriptionLinking = 'transcluding'; break; default: ApiBase::dieDebug(__METHOD__, 'Unknown module name'); } parent::__construct($query, $moduleName, $prefix); }
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); }
public function execute() { $data = $this->getResultData(); if (isset($data['error'])) { $this->mErrorFallback->execute(); return; } if (!isset($data['text'])) { ApiBase::dieDebug(__METHOD__, 'No text given for raw formatter'); } $this->printText($data['text']); }
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; } }
public function execute() { $data = $this->getResult()->getResultData(); if (isset($data['error'])) { $this->errorFallback->execute(); return; } if (isset($data['file'])) { $this->file = $data['file']; } elseif (isset($data['text'])) { $this->printText($data['text']); } else { ApiBase::dieDebug(__METHOD__, 'No text or file given for file formatter'); } }
public function execute() { global $wgUser; // Before doing anything at all, let's check permissions if (!$wgUser->isAllowed('codereview-use')) { $this->dieUsage('You don\'t have permission to update code', 'permissiondenied'); } $params = $this->extractRequestParams(); $repo = CodeRepository::newFromName($params['repo']); if (!$repo) { $this->dieUsage("Invalid repo ``{$params['repo']}''", 'invalidrepo'); } $svn = SubversionAdaptor::newFromRepo($repo->getPath()); $lastStoredRev = $repo->getLastStoredRev(); if ($lastStoredRev >= $params['rev']) { // Nothing to do, we're up to date. // Return an empty result $this->getResult()->addValue(null, $this->getModuleName(), array()); return; } // FIXME: this could be a lot? $log = $svn->getLog('', $lastStoredRev + 1, $params['rev']); if (!$log) { // FIXME: When and how often does this happen? // Should we use dieUsage() here instead? ApiBase::dieDebug(__METHOD__, 'Something awry...'); } $result = array(); $revs = array(); foreach ($log as $data) { $codeRev = CodeRevision::newFromSvn($repo, $data); $codeRev->save(); $result[] = array('id' => $codeRev->getId(), 'author' => $codeRev->getAuthor(), 'timestamp' => wfTimestamp(TS_ISO_8601, $codeRev->getTimestamp()), 'message' => $codeRev->getMessage()); $revs[] = $codeRev; } // Cache the diffs if there are a only a few. // Mainly for WMF post-commit ping hook... if (count($revs) <= 2) { foreach ($revs as $codeRev) { $repo->setDiffCache($codeRev); // trigger caching } } $this->getResult()->setIndexedTagName($result, 'rev'); $this->getResult()->addValue(null, $this->getModuleName(), $result); }
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() { $params = $this->extractRequestParams(); $result = array(); switch ( $params['field'] ) { case "username": $mUser = User::newFromName( $params['inputVal'], 'creatable' ); if ( !is_object( $mUser ) ) { $result['result'] = wfMsg( 'signupapi-noname' ); $result['icon'] = 'MW-Icon-AlertMark.png'; } if ( 0 != $mUser->idForName() ) { $result['result'] = wfMsg( 'signupapi-userexists' ); $result['icon'] = "MW-Icon-NoMark.png"; } else { $result['result'] = wfMsg( 'signupapi-ok' ); $result['icon'] = "MW-Icon-CheckMark.png"; } break; case "email" : $valid = User::isValidEmailAddr( $params['inputVal'] ); if ( $valid ) { $result['result']= wfMsg( 'signupapi-ok' ); $result['icon'] = "MW-Icon-CheckMark.png"; } else { $result['result']= wfMsg( 'signupapi-invalidemailaddress' ); $result['icon'] = "MW-Icon-NoMark.png"; } break; case "passwordlength" : global $wgMinimalPasswordLength; $result['result'] = $wgMinimalPasswordLength; break; default : ApiBase::dieDebug( __METHOD__, "Unhandled case value: {$params['field']}" ); } $this->getResult()->addValue( null, 'signup', $result ); }
public function __construct(ApiQuery $query, $moduleName) { switch ($moduleName) { case self::LINKS: $this->table = 'pagelinks'; $this->prefix = 'pl'; $this->titlesParam = 'titles'; $this->helpUrl = 'https://www.mediawiki.org/wiki/API:Links'; break; case self::TEMPLATES: $this->table = 'templatelinks'; $this->prefix = 'tl'; $this->titlesParam = 'templates'; $this->helpUrl = 'https://www.mediawiki.org/wiki/API:Templates'; break; default: ApiBase::dieDebug(__METHOD__, 'Unknown module name'); } parent::__construct($query, $moduleName, $this->prefix); }
public function execute() { global $wgUser; $this->checkPermission($wgUser); $params = $this->extractRequestParams(); $res = array(); $concurrencyCheck = new ConcurrencyCheck($params['resourcetype'], $wgUser); switch ($params['ccaction']) { case 'checkout': case 'checkin': if ($concurrencyCheck->{$params}['ccaction']($params['record'])) { $res['result'] = 'success'; } else { $res['result'] = 'failure'; } break; default: ApiBase::dieDebug(__METHOD__, "Unhandled concurrency action: {$params['ccaction']}"); } $this->getResult()->addValue(null, $this->getModuleName(), $res); }
public function execute() { $name = $password = $domain = null; extract($this->extractRequestParams()); $params = new FauxRequest(array('wpName' => $name, 'wpPassword' => $password, 'wpDomain' => $domain, 'wpRemember' => '')); $result = array(); $loginForm = new LoginForm($params); switch ($loginForm->authenticateUserData()) { case LoginForm::SUCCESS: global $wgUser; $wgUser->setOption('rememberpassword', 1); $wgUser->setCookies(); $result['result'] = 'Success'; $result['lguserid'] = $_SESSION['wsUserID']; $result['lgusername'] = $_SESSION['wsUserName']; $result['lgtoken'] = $_SESSION['wsToken']; break; case LoginForm::NO_NAME: $result['result'] = 'NoName'; break; case LoginForm::ILLEGAL: $result['result'] = 'Illegal'; break; case LoginForm::WRONG_PLUGIN_PASS: $result['result'] = 'WrongPluginPass'; break; case LoginForm::NOT_EXISTS: $result['result'] = 'NotExists'; break; case LoginForm::WRONG_PASS: $result['result'] = 'WrongPass'; break; case LoginForm::EMPTY_PASS: $result['result'] = 'EmptyPass'; break; default: ApiBase::dieDebug(__METHOD__, 'Unhandled case value'); } $this->getResult()->addValue(null, 'login', $result); }
public function __construct(ApiQuery $query, $moduleName) { switch ($moduleName) { case 'alllinks': $prefix = 'al'; $this->table = 'pagelinks'; $this->tablePrefix = 'pl_'; $this->useIndex = 'pl_namespace'; $this->indexTag = 'l'; break; case 'alltransclusions': $prefix = 'at'; $this->table = 'templatelinks'; $this->tablePrefix = 'tl_'; $this->dfltNamespace = NS_TEMPLATE; $this->useIndex = 'tl_namespace'; $this->indexTag = 't'; break; case 'allfileusages': $prefix = 'af'; $this->table = 'imagelinks'; $this->tablePrefix = 'il_'; $this->fieldTitle = 'to'; $this->dfltNamespace = NS_FILE; $this->hasNamespace = false; $this->indexTag = 'f'; break; case 'allredirects': $prefix = 'ar'; $this->table = 'redirect'; $this->tablePrefix = 'rd_'; $this->indexTag = 'r'; $this->props = array('fragment' => 'rd_fragment', 'interwiki' => 'rd_interwiki'); break; default: ApiBase::dieDebug(__METHOD__, 'Unknown module name'); } parent::__construct($query, $moduleName, $prefix); }
/** * Recursivelly go through the object and output its data in WDDX format. */ function slowWddxPrinter($elemValue) { switch (gettype($elemValue)) { case 'array': $this->printText('<struct>'); foreach ($elemValue as $subElemName => $subElemValue) { $this->printText(wfElement('var', array('name' => $subElemName), null)); $this->slowWddxPrinter($subElemValue); $this->printText('</var>'); } $this->printText('</struct>'); break; case 'integer': case 'double': $this->printText(wfElement('number', null, $elemValue)); break; case 'string': $this->printText(wfElement('string', null, $elemValue)); break; default: ApiBase::dieDebug(__METHOD__, 'Unknown type ' . gettype($elemValue)); } }
public function __construct(ApiQuery $query, $moduleName) { switch ($moduleName) { case self::LINKS: $this->table = 'pagelinks'; $this->prefix = 'pl'; $this->description = 'link'; $this->titlesParam = 'titles'; $this->titlesParamDescription = 'Only list links to these titles. Useful ' . 'for checking whether a certain page links to a certain title.'; $this->helpUrl = 'https://www.mediawiki.org/wiki/API:Properties#links_.2F_pl'; break; case self::TEMPLATES: $this->table = 'templatelinks'; $this->prefix = 'tl'; $this->description = 'template'; $this->titlesParam = 'templates'; $this->titlesParamDescription = 'Only list these templates. Useful ' . 'for checking whether a certain page uses a certain template.'; $this->helpUrl = 'https://www.mediawiki.org/wiki/API:Properties#templates_.2F_tl'; break; default: ApiBase::dieDebug(__METHOD__, 'Unknown module name'); } parent::__construct($query, $moduleName, $this->prefix); }
/** * Recursively go through the object and output its data in WDDX format. * @param $elemValue * @param $indent int */ function slowWddxPrinter($elemValue, $indent = 0) { $indstr = $this->getIsHtml() ? str_repeat(' ', $indent) : ''; $indstr2 = $this->getIsHtml() ? str_repeat(' ', $indent + 2) : ''; $nl = $this->getIsHtml() ? "\n" : ''; if (is_array($elemValue)) { // Check whether we've got an associative array (<struct>) // or a regular array (<array>) $cnt = count($elemValue); if ($cnt == 0 || array_keys($elemValue) === range(0, $cnt - 1)) { // Regular array $this->printText($indstr . Xml::element('array', array('length' => $cnt), null) . $nl); foreach ($elemValue as $subElemValue) { $this->slowWddxPrinter($subElemValue, $indent + 2); } $this->printText("{$indstr}</array>{$nl}"); } else { // Associative array (<struct>) $this->printText("{$indstr}<struct>{$nl}"); foreach ($elemValue as $subElemName => $subElemValue) { $this->printText($indstr2 . Xml::element('var', array('name' => $subElemName), null) . $nl); $this->slowWddxPrinter($subElemValue, $indent + 4); $this->printText("{$indstr2}</var>{$nl}"); } $this->printText("{$indstr}</struct>{$nl}"); } } elseif (is_int($elemValue) || is_float($elemValue)) { $this->printText($indstr . Xml::element('number', null, $elemValue) . $nl); } elseif (is_string($elemValue)) { $this->printText($indstr . Xml::element('string', null, $elemValue) . $nl); } elseif (is_bool($elemValue)) { $this->printText($indstr . Xml::element('boolean', array('value' => $elemValue ? 'true' : 'false')) . $nl); } else { ApiBase::dieDebug(__METHOD__, 'Unknown type ' . gettype($elemValue)); } }
/** * Create instances of all modules requested by the client * @param array $modules to append instantiated modules to * @param string $param Parameter name to read modules from */ private function instantiateModules(&$modules, $param) { if (isset($this->mParams[$param])) { foreach ($this->mParams[$param] as $moduleName) { $instance = $this->mModuleMgr->getModule($moduleName, $param); if ($instance === null) { ApiBase::dieDebug(__METHOD__, 'Error instantiating module'); } // Ignore duplicates. TODO 2.0: die()? if (!array_key_exists($moduleName, $modules)) { $modules[$moduleName] = $instance; } } } }
/** * Total time the module used the database * @return float */ public function getProfileDBTime() { if ($this->mDBTimeIn !== 0) { ApiBase::dieDebug(__METHOD__, 'called without calling profileDBOut() first'); } return $this->mDBTime; }
protected function appendInterwikiMap($property, $filter) { $local = null; if ($filter === 'local') { $local = 1; } elseif ($filter === '!local') { $local = 0; } elseif ($filter) { ApiBase::dieDebug(__METHOD__, "Unknown filter={$filter}"); } $params = $this->extractRequestParams(); $langCode = isset($params['inlanguagecode']) ? $params['inlanguagecode'] : ''; if ($langCode) { $langNames = Language::getTranslatedLanguageNames($langCode); } else { $langNames = Language::getLanguageNames(); } $getPrefixes = Interwiki::getAllPrefixes($local); $data = array(); foreach ($getPrefixes as $row) { $prefix = $row['iw_prefix']; $val = array(); $val['prefix'] = $prefix; if ($row['iw_local'] == '1') { $val['local'] = ''; } // $val['trans'] = intval( $row['iw_trans'] ); // should this be exposed? if (isset($langNames[$prefix])) { $val['language'] = $langNames[$prefix]; } $val['url'] = wfExpandUrl($row['iw_url'], PROTO_CURRENT); if (isset($row['iw_wikiid'])) { $val['wikiid'] = $row['iw_wikiid']; } if (isset($row['iw_api'])) { $val['api'] = $row['iw_api']; } $data[] = $val; } $this->getResult()->setIndexedTagName($data, 'iw'); return $this->getResult()->addValue('query', $property, $data); }
protected function run(ApiPageSet $resultPageSet = null) { $params = $this->extractRequestParams(false); // 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($params['user']) || !is_null($params['excludeuser']) || !is_null($params['limit']) || !is_null($params['startid']) || !is_null($params['endid']) || $params['dir'] === 'newer' || !is_null($params['start']) || !is_null($params['end']); $pageSet = $this->getPageSet(); $pageCount = $pageSet->getGoodTitleCount(); $revCount = $pageSet->getRevisionCount(); // Optimization -- nothing to do if ($revCount === 0 && $pageCount === 0) { // Nothing to do return; } if ($revCount > 0 && count($pageSet->getLiveRevisionIDs()) === 0) { // We're in revisions mode but all given revisions are deleted 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'); } // In non-enum mode, rvlimit can't be directly used. Use the maximum // allowed value. if (!$enumRevMode) { $this->setParsedLimit = false; $params['limit'] = 'max'; } $db = $this->getDB(); $this->addTables(array('revision', 'page')); $this->addJoinConds(array('page' => array('INNER JOIN', array('page_id = rev_page')))); if ($resultPageSet === null) { $this->parseParameters($params); $this->token = $params['token']; $this->addFields(Revision::selectFields()); if ($this->token !== null || $pageCount > 0) { $this->addFields(Revision::selectPageFields()); } } else { $this->limit = $this->getParameter('limit') ?: 10; $this->addFields(array('rev_id', 'rev_page')); } if ($this->fld_tags) { $this->addTables('tag_summary'); $this->addJoinConds(array('tag_summary' => array('LEFT JOIN', array('rev_id=ts_rev_id')))); $this->addFields('ts_tags'); } if (!is_null($params['tag'])) { $this->addTables('change_tag'); $this->addJoinConds(array('change_tag' => array('INNER JOIN', array('rev_id=ct_rev_id')))); $this->addWhereFld('ct_tag', $params['tag']); } if ($this->fetchContent) { // For each page we will request, the user must have read rights for that page $user = $this->getUser(); /** @var $title Title */ foreach ($pageSet->getGoodTitles() as $title) { if (!$title->userCan('read', $user)) { $this->dieUsage('The current user is not allowed to read ' . $title->getPrefixedText(), 'accessdenied'); } } $this->addTables('text'); $this->addJoinConds(array('text' => array('INNER JOIN', array('rev_text_id=old_id')))); $this->addFields('old_id'); $this->addFields(Revision::selectTextFields()); } // add user name, if needed if ($this->fld_user) { $this->addTables('user'); $this->addJoinConds(array('user' => Revision::userJoinCond())); $this->addFields(Revision::selectUserFields()); } if ($enumRevMode) { // This is mostly to prevent parameter errors (and optimize SQL?) if (!is_null($params['startid']) && !is_null($params['start'])) { $this->dieUsage('start and startid cannot be used together', 'badparams'); } if (!is_null($params['endid']) && !is_null($params['end'])) { $this->dieUsage('end and endid cannot be used together', 'badparams'); } if (!is_null($params['user']) && !is_null($params['excludeuser'])) { $this->dieUsage('user and excludeuser cannot be used together', 'badparams'); } // Continuing effectively uses startid. But we can't use rvstartid // directly, because there is no way to tell the client to ''not'' // send rvstart if it sent it in the original query. So instead we // send the continuation startid as rvcontinue, and ignore both // rvstart and rvstartid when that is supplied. if (!is_null($params['continue'])) { $params['startid'] = $params['continue']; $params['start'] = null; } // 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($params['startid']) && is_null($params['endid'])) { $this->addTimestampWhereRange('rev_timestamp', $params['dir'], $params['start'], $params['end']); } else { $this->addWhereRange('rev_id', $params['dir'], $params['startid'], $params['endid']); // One of start and end can be set // If neither is set, this does nothing $this->addTimestampWhereRange('rev_timestamp', $params['dir'], $params['start'], $params['end'], false); } // There is only one ID, use it $ids = array_keys($pageSet->getGoodTitles()); $this->addWhereFld('rev_page', reset($ids)); if (!is_null($params['user'])) { $this->addWhereFld('rev_user_text', $params['user']); } elseif (!is_null($params['excludeuser'])) { $this->addWhere('rev_user_text != ' . $db->addQuotes($params['excludeuser'])); } if (!is_null($params['user']) || !is_null($params['excludeuser'])) { // Paranoia: avoid brute force searches (bug 17342) if (!$this->getUser()->isAllowed('deletedhistory')) { $bitmask = Revision::DELETED_USER; } elseif (!$this->getUser()->isAllowedAny('suppressrevision', 'viewsuppressed')) { $bitmask = Revision::DELETED_USER | Revision::DELETED_RESTRICTED; } else { $bitmask = 0; } if ($bitmask) { $this->addWhere($db->bitAnd('rev_deleted', $bitmask) . " != {$bitmask}"); } } } elseif ($revCount > 0) { $revs = $pageSet->getLiveRevisionIDs(); // Get all revision IDs $this->addWhereFld('rev_id', array_keys($revs)); if (!is_null($params['continue'])) { $this->addWhere('rev_id >= ' . intval($params['continue'])); } $this->addOption('ORDER BY', 'rev_id'); } elseif ($pageCount > 0) { $titles = $pageSet->getGoodTitles(); // When working in multi-page non-enumeration mode, // limit to the latest revision only $this->addWhere('page_latest=rev_id'); // Get all page IDs $this->addWhereFld('page_id', array_keys($titles)); // Every time someone relies on equality propagation, god kills a kitten :) $this->addWhereFld('rev_page', array_keys($titles)); if (!is_null($params['continue'])) { $cont = explode('|', $params['continue']); $this->dieContinueUsageIf(count($cont) != 2); $pageid = intval($cont[0]); $revid = intval($cont[1]); $this->addWhere("rev_page > {$pageid} OR " . "(rev_page = {$pageid} AND " . "rev_id >= {$revid})"); } $this->addOption('ORDER BY', array('rev_page', 'rev_id')); } else { ApiBase::dieDebug(__METHOD__, 'param validation?'); } $this->addOption('LIMIT', $this->limit + 1); $count = 0; $generated = array(); $res = $this->select(__METHOD__); foreach ($res as $row) { if (++$count > $this->limit) { // We've reached the one extra which shows that there are // additional pages to be had. Stop here... if ($enumRevMode) { $this->setContinueEnumParameter('continue', intval($row->rev_id)); } elseif ($revCount > 0) { $this->setContinueEnumParameter('continue', intval($row->rev_id)); } else { $this->setContinueEnumParameter('continue', intval($row->rev_page) . '|' . intval($row->rev_id)); } break; } if ($resultPageSet !== null) { $generated[] = $row->rev_id; } else { $revision = new Revision($row); $rev = $this->extractRevisionInfo($revision, $row); if ($this->token !== null) { $title = $revision->getTitle(); $tokenFunctions = $this->getTokenFunctions(); foreach ($this->token as $t) { $val = call_user_func($tokenFunctions[$t], $title->getArticleID(), $title, $revision); if ($val === false) { $this->setWarning("Action '{$t}' is not allowed for the current user"); } else { $rev[$t . 'token'] = $val; } } } $fit = $this->addPageSubItem($row->rev_page, $rev, 'rev'); if (!$fit) { if ($enumRevMode) { $this->setContinueEnumParameter('continue', intval($row->rev_id)); } elseif ($revCount > 0) { $this->setContinueEnumParameter('continue', intval($row->rev_id)); } else { $this->setContinueEnumParameter('continue', intval($row->rev_page) . '|' . intval($row->rev_id)); } break; } } } if ($resultPageSet !== null) { $resultPageSet->populateFromRevisionIDs($generated); } }
/** * Using the settings determine the value for the given parameter * * @param string $paramName Parameter name * @param array|mixed $paramSettings Default value or an array of settings * using PARAM_* constants. * @param bool $parseLimit Parse limit? * @return mixed Parameter value */ protected function getParameterFromSettings($paramName, $paramSettings, $parseLimit) { // Some classes may decide to change parameter names $encParamName = $this->encodeParamName($paramName); if (!is_array($paramSettings)) { $default = $paramSettings; $multi = false; $type = gettype($paramSettings); $dupes = false; $deprecated = false; $required = false; } else { $default = isset($paramSettings[self::PARAM_DFLT]) ? $paramSettings[self::PARAM_DFLT] : null; $multi = isset($paramSettings[self::PARAM_ISMULTI]) ? $paramSettings[self::PARAM_ISMULTI] : false; $type = isset($paramSettings[self::PARAM_TYPE]) ? $paramSettings[self::PARAM_TYPE] : null; $dupes = isset($paramSettings[self::PARAM_ALLOW_DUPLICATES]) ? $paramSettings[self::PARAM_ALLOW_DUPLICATES] : false; $deprecated = isset($paramSettings[self::PARAM_DEPRECATED]) ? $paramSettings[self::PARAM_DEPRECATED] : false; $required = isset($paramSettings[self::PARAM_REQUIRED]) ? $paramSettings[self::PARAM_REQUIRED] : false; // When type is not given, and no choices, the type is the same as $default if (!isset($type)) { if (isset($default)) { $type = gettype($default); } else { $type = 'NULL'; // allow everything } } } if ($type == 'boolean') { if (isset($default) && $default !== false) { // Having a default value of anything other than 'false' is not allowed ApiBase::dieDebug(__METHOD__, "Boolean param {$encParamName}'s default is set to '{$default}'. " . "Boolean parameters must default to false."); } $value = $this->getMain()->getCheck($encParamName); } elseif ($type == 'upload') { if (isset($default)) { // Having a default value is not allowed ApiBase::dieDebug(__METHOD__, "File upload param {$encParamName}'s default is set to " . "'{$default}'. File upload parameters may not have a default."); } if ($multi) { ApiBase::dieDebug(__METHOD__, "Multi-values not supported for {$encParamName}"); } $value = $this->getMain()->getUpload($encParamName); if (!$value->exists()) { // This will get the value without trying to normalize it // (because trying to normalize a large binary file // accidentally uploaded as a field fails spectacularly) $value = $this->getMain()->getRequest()->unsetVal($encParamName); if ($value !== null) { $this->dieUsage("File upload param {$encParamName} is not a file upload; " . "be sure to use multipart/form-data for your POST and include " . "a filename in the Content-Disposition header.", "badupload_{$encParamName}"); } } } else { $value = $this->getMain()->getVal($encParamName, $default); if (isset($value) && $type == 'namespace') { $type = MWNamespace::getValidNamespaces(); } if (isset($value) && $type == 'submodule') { if (isset($paramSettings[self::PARAM_SUBMODULE_MAP])) { $type = array_keys($paramSettings[self::PARAM_SUBMODULE_MAP]); } else { $type = $this->getModuleManager()->getNames($paramName); } } } if (isset($value) && ($multi || is_array($type))) { $value = $this->parseMultiValue($encParamName, $value, $multi, is_array($type) ? $type : null); } // More validation only when choices were not given // choices were validated in parseMultiValue() if (isset($value)) { if (!is_array($type)) { switch ($type) { case 'NULL': // nothing to do break; case 'string': case 'text': case 'password': if ($required && $value === '') { $this->dieUsageMsg(array('missingparam', $paramName)); } break; case 'integer': // Force everything using intval() and optionally validate limits $min = isset($paramSettings[self::PARAM_MIN]) ? $paramSettings[self::PARAM_MIN] : null; $max = isset($paramSettings[self::PARAM_MAX]) ? $paramSettings[self::PARAM_MAX] : null; $enforceLimits = isset($paramSettings[self::PARAM_RANGE_ENFORCE]) ? $paramSettings[self::PARAM_RANGE_ENFORCE] : false; if (is_array($value)) { $value = array_map('intval', $value); if (!is_null($min) || !is_null($max)) { foreach ($value as &$v) { $this->validateLimit($paramName, $v, $min, $max, null, $enforceLimits); } } } else { $value = intval($value); if (!is_null($min) || !is_null($max)) { $this->validateLimit($paramName, $value, $min, $max, null, $enforceLimits); } } break; case 'limit': if (!$parseLimit) { // Don't do any validation whatsoever break; } if (!isset($paramSettings[self::PARAM_MAX]) || !isset($paramSettings[self::PARAM_MAX2])) { ApiBase::dieDebug(__METHOD__, "MAX1 or MAX2 are not defined for the limit {$encParamName}"); } if ($multi) { ApiBase::dieDebug(__METHOD__, "Multi-values not supported for {$encParamName}"); } $min = isset($paramSettings[self::PARAM_MIN]) ? $paramSettings[self::PARAM_MIN] : 0; if ($value == 'max') { $value = $this->getMain()->canApiHighLimits() ? $paramSettings[self::PARAM_MAX2] : $paramSettings[self::PARAM_MAX]; $this->getResult()->addParsedLimit($this->getModuleName(), $value); } else { $value = intval($value); $this->validateLimit($paramName, $value, $min, $paramSettings[self::PARAM_MAX], $paramSettings[self::PARAM_MAX2]); } break; case 'boolean': if ($multi) { ApiBase::dieDebug(__METHOD__, "Multi-values not supported for {$encParamName}"); } break; case 'timestamp': if (is_array($value)) { foreach ($value as $key => $val) { $value[$key] = $this->validateTimestamp($val, $encParamName); } } else { $value = $this->validateTimestamp($value, $encParamName); } break; case 'user': if (is_array($value)) { foreach ($value as $key => $val) { $value[$key] = $this->validateUser($val, $encParamName); } } else { $value = $this->validateUser($value, $encParamName); } break; case 'upload': // nothing to do break; default: ApiBase::dieDebug(__METHOD__, "Param {$encParamName}'s type is unknown - {$type}"); } } // Throw out duplicates if requested if (!$dupes && is_array($value)) { $value = array_unique($value); } // Set a warning if a deprecated parameter has been passed if ($deprecated && $value !== false) { $this->setWarning("The {$encParamName} parameter has been deprecated."); $feature = $encParamName; $m = $this; while (!$m->isMain()) { $p = $m->getParent(); $name = $m->getModuleName(); $param = $p->encodeParamName($p->getModuleManager()->getModuleGroup($name)); $feature = "{$param}={$name}&{$feature}"; $m = $p; } $this->logFeatureUsage($feature); } } elseif ($required) { $this->dieUsageMsg(array('missingparam', $paramName)); } return $value; }
public function execute() { ApiBase::dieDebug(__METHOD__, 'execute() is not supported on Result object'); }
/** * Add a set of JOIN conditions to the internal array * * JOIN conditions are formatted as array( tablename => array(jointype, * conditions) e.g. array('page' => array('LEFT JOIN', * 'page_id=rev_page')) . conditions may be a string or an * addWhere()-style array * @param $join_conds array JOIN conditions */ protected function addJoinConds($join_conds) { if (!is_array($join_conds)) { ApiBase::dieDebug(__METHOD__, 'Join conditions have to be arrays'); } $this->join_conds = array_merge($this->join_conds, $join_conds); }
/** * Recursively go through the object and output its data in WDDX format. * @param $elemValue * @param $indent int */ function slowWddxPrinter($elemValue, $indent = 0) { $indstr = $this->getIsHtml() ? '' : str_repeat(' ', $indent); $indstr2 = $this->getIsHtml() ? '' : str_repeat(' ', $indent + 2); $nl = $this->getIsHtml() ? '' : "\n"; switch (gettype($elemValue)) { case 'array': // Check whether we've got an associative array (<struct>) // or a regular array (<array>) $cnt = count($elemValue); if ($cnt == 0 || array_keys($elemValue) === range(0, $cnt - 1)) { // Regular array $this->printText($indstr . Xml::element('array', array('length' => $cnt), null) . $nl); foreach ($elemValue as $subElemValue) { $this->slowWddxPrinter($subElemValue, $indent + 2); } $this->printText("{$indstr}</array>{$nl}"); } else { // Associative array (<struct>) $this->printText("{$indstr}<struct>{$nl}"); foreach ($elemValue as $subElemName => $subElemValue) { $this->printText($indstr2 . Xml::element('var', array('name' => $subElemName), null) . $nl); $this->slowWddxPrinter($subElemValue, $indent + 4); $this->printText("{$indstr2}</var>{$nl}"); } $this->printText("{$indstr}</struct>{$nl}"); } break; case 'integer': case 'double': $this->printText($indstr . Xml::element('number', null, $elemValue) . $nl); break; case 'string': $this->printText($indstr . Xml::element('string', null, $elemValue) . $nl); break; default: ApiBase::dieDebug(__METHOD__, 'Unknown type ' . gettype($elemValue)); } }
/** * Executes the log-in attempt using the parameters passed. If * the log-in succeeeds, it attaches a cookie to the session * and outputs the user id, username, and session token. If a * log-in fails, as the result of a bad password, a nonexistent * user, or any other reason, the host is cached with an expiry * and no log-in attempts will be accepted until that expiry * is reached. The expiry is $this->mLoginThrottle. */ public function execute() { $params = $this->extractRequestParams(); $result = array(); // Init session if necessary if (session_id() == '') { wfSetupSession(); } $context = new DerivativeContext($this->getContext()); $context->setRequest(new DerivativeRequest($this->getContext()->getRequest(), array('wpName' => $params['name'], 'wpPassword' => $params['password'], 'wpDomain' => $params['domain'], 'wpLoginToken' => $params['token'], 'wpRemember' => ''))); $loginForm = new LoginForm(); $loginForm->setContext($context); global $wgCookiePrefix, $wgPasswordAttemptThrottle; $authRes = $loginForm->authenticateUserData(); switch ($authRes) { case LoginForm::SUCCESS: $user = $context->getUser(); $this->getContext()->setUser($user); $user->setOption('rememberpassword', 1); $user->setCookies($this->getRequest()); ApiQueryInfo::resetTokenCache(); // Run hooks. // @todo FIXME: Split back and frontend from this hook. // @todo FIXME: This hook should be placed in the backend $injected_html = ''; wfRunHooks('UserLoginComplete', array(&$user, &$injected_html)); $result['result'] = 'Success'; $result['lguserid'] = intval($user->getId()); $result['lgusername'] = $user->getName(); $result['lgtoken'] = $user->getToken(); $result['cookieprefix'] = $wgCookiePrefix; $result['sessionid'] = session_id(); break; case LoginForm::NEED_TOKEN: $result['result'] = 'NeedToken'; $result['token'] = $loginForm->getLoginToken(); $result['cookieprefix'] = $wgCookiePrefix; $result['sessionid'] = session_id(); break; case LoginForm::WRONG_TOKEN: $result['result'] = 'WrongToken'; break; case LoginForm::NO_NAME: $result['result'] = 'NoName'; break; case LoginForm::ILLEGAL: $result['result'] = 'Illegal'; break; case LoginForm::WRONG_PLUGIN_PASS: $result['result'] = 'WrongPluginPass'; break; case LoginForm::NOT_EXISTS: $result['result'] = 'NotExists'; break; case LoginForm::RESET_PASS: // bug 20223 - Treat a temporary password as wrong. Per SpecialUserLogin - "The e-mailed temporary password should not be used for actual logins;" // bug 20223 - Treat a temporary password as wrong. Per SpecialUserLogin - "The e-mailed temporary password should not be used for actual logins;" case LoginForm::WRONG_PASS: $result['result'] = 'WrongPass'; break; case LoginForm::EMPTY_PASS: $result['result'] = 'EmptyPass'; break; case LoginForm::CREATE_BLOCKED: $result['result'] = 'CreateBlocked'; $result['details'] = 'Your IP address is blocked from account creation'; break; case LoginForm::THROTTLED: $result['result'] = 'Throttled'; $result['wait'] = intval($wgPasswordAttemptThrottle['seconds']); break; case LoginForm::USER_BLOCKED: $result['result'] = 'Blocked'; break; case LoginForm::ABORTED: $result['result'] = 'Aborted'; $result['reason'] = $loginForm->mAbortLoginErrorMsg; break; default: ApiBase::dieDebug(__METHOD__, "Unhandled case value: {$authRes}"); } $this->getResult()->addValue(null, 'login', $result); }
/** * Iterate through the result of the query on 'page' table, * and for each row create and store title object and save any extra fields requested. * @param $res ResultWrapper DB Query result * @param $remaining array of either pageID or ns/title elements (optional). * If given, any missing items will go to $mMissingPageIDs and $mMissingTitles * @param $processTitles bool Must be provided together with $remaining. * If true, treat $remaining as an array of [ns][title] * If false, treat it as an array of [pageIDs] */ private function initFromQueryResult($res, &$remaining = null, $processTitles = null) { if (!is_null($remaining) && is_null($processTitles)) { ApiBase::dieDebug(__METHOD__, 'Missing $processTitles parameter when $remaining is provided'); } if ($res) { foreach ($res as $row) { $pageId = intval($row->page_id); // Remove found page from the list of remaining items if (isset($remaining)) { if ($processTitles) { unset($remaining[$row->page_namespace][$row->page_title]); } else { unset($remaining[$pageId]); } } // Store any extra fields requested by modules $this->processDbRow($row); } } if (isset($remaining)) { // Any items left in the $remaining list are added as missing if ($processTitles) { // The remaining titles in $remaining are non-existent pages foreach ($remaining as $ns => $dbkeys) { foreach (array_keys($dbkeys) as $dbkey) { $title = Title::makeTitle($ns, $dbkey); $this->mAllPages[$ns][$dbkey] = $this->mFakePageId; $this->mMissingTitles[$this->mFakePageId] = $title; $this->mFakePageId--; $this->mTitles[] = $title; } } } else { // The remaining pageids do not exist if (!$this->mMissingPageIDs) { $this->mMissingPageIDs = array_keys($remaining); } else { $this->mMissingPageIDs = array_merge($this->mMissingPageIDs, array_keys($remaining)); } } } }
/** * Generates and outputs the result of this query based upon the provided parameters. * * @param ApiPageSet $resultPageSet */ public function run($resultPageSet = null) { $user = $this->getUser(); /* Get the parameters of the request. */ $params = $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 */ $this->addTables('recentchanges'); $index = array('recentchanges' => 'rc_timestamp'); // May change $this->addTimestampWhereRange('rc_timestamp', $params['dir'], $params['start'], $params['end']); if (!is_null($params['continue'])) { $cont = explode('|', $params['continue']); $this->dieContinueUsageIf(count($cont) != 2); $db = $this->getDB(); $timestamp = $db->addQuotes($db->timestamp($cont[0])); $id = intval($cont[1]); $this->dieContinueUsageIf($id != $cont[1]); $op = $params['dir'] === 'older' ? '<' : '>'; $this->addWhere("rc_timestamp {$op} {$timestamp} OR " . "(rc_timestamp = {$timestamp} AND " . "rc_id {$op}= {$id})"); } $order = $params['dir'] === 'older' ? 'DESC' : 'ASC'; $this->addOption('ORDER BY', array("rc_timestamp {$order}", "rc_id {$order}")); $this->addWhereFld('rc_namespace', $params['namespace']); if (!is_null($params['type'])) { try { $this->addWhereFld('rc_type', RecentChange::parseToRCType($params['type'])); } catch (Exception $e) { ApiBase::dieDebug(__METHOD__, $e->getMessage()); } } if (!is_null($params['show'])) { $show = array_flip($params['show']); /* Check for conflicting parameters. */ if (isset($show['minor']) && isset($show['!minor']) || isset($show['bot']) && isset($show['!bot']) || isset($show['anon']) && isset($show['!anon']) || isset($show['redirect']) && isset($show['!redirect']) || isset($show['patrolled']) && isset($show['!patrolled']) || isset($show['patrolled']) && isset($show['unpatrolled']) || isset($show['!patrolled']) && isset($show['unpatrolled'])) { $this->dieUsageMsg('show'); } // Check permissions if (isset($show['patrolled']) || isset($show['!patrolled']) || isset($show['unpatrolled'])) { if (!$user->useRCPatrol() && !$user->useNPPatrol()) { $this->dieUsage('You need the patrol right to request the patrolled flag', 'permissiondenied'); } } /* 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'])); $this->addWhereIf('rc_patrolled = 0', isset($show['!patrolled'])); $this->addWhereIf('rc_patrolled != 0', isset($show['patrolled'])); $this->addWhereIf('page_is_redirect = 1', isset($show['redirect'])); if (isset($show['unpatrolled'])) { // See ChangesList:isUnpatrolled if ($user->useRCPatrol()) { $this->addWhere('rc_patrolled = 0'); } elseif ($user->useNPPatrol()) { $this->addWhere('rc_patrolled = 0'); $this->addWhereFld('rc_type', RC_NEW); } } // Don't throw log entries out the window here $this->addWhereIf('page_is_redirect = 0 OR page_is_redirect IS NULL', isset($show['!redirect'])); } if (!is_null($params['user']) && !is_null($params['excludeuser'])) { $this->dieUsage('user and excludeuser cannot be used together', 'user-excludeuser'); } if (!is_null($params['user'])) { $this->addWhereFld('rc_user_text', $params['user']); $index['recentchanges'] = 'rc_user_text'; } if (!is_null($params['excludeuser'])) { // We don't use the rc_user_text index here because // * it would require us to sort by rc_user_text before rc_timestamp // * the != condition doesn't throw out too many rows anyway $this->addWhere('rc_user_text != ' . $this->getDB()->addQuotes($params['excludeuser'])); } /* Add the fields we're concerned with to our query. */ $this->addFields(array('rc_id', 'rc_timestamp', 'rc_namespace', 'rc_title', 'rc_cur_id', 'rc_type', 'rc_deleted')); $showRedirects = false; /* Determine what properties we need to display. */ if (!is_null($params['prop'])) { $prop = array_flip($params['prop']); /* Set up internal members based upon params. */ $this->initProperties($prop); if ($this->fld_patrolled && !$user->useRCPatrol() && !$user->useNPPatrol()) { $this->dieUsage('You need the patrol right to request the patrolled flag', 'permissiondenied'); } /* Add fields to our query if they are specified as a needed parameter. */ $this->addFieldsIf(array('rc_this_oldid', 'rc_last_oldid'), $this->fld_ids); $this->addFieldsIf('rc_comment', $this->fld_comment || $this->fld_parsedcomment); $this->addFieldsIf('rc_user', $this->fld_user || $this->fld_userid); $this->addFieldsIf('rc_user_text', $this->fld_user); $this->addFieldsIf(array('rc_minor', 'rc_type', 'rc_bot'), $this->fld_flags); $this->addFieldsIf(array('rc_old_len', 'rc_new_len'), $this->fld_sizes); $this->addFieldsIf('rc_patrolled', $this->fld_patrolled); $this->addFieldsIf(array('rc_logid', 'rc_log_type', 'rc_log_action', 'rc_params'), $this->fld_loginfo); $showRedirects = $this->fld_redirect || isset($show['redirect']) || isset($show['!redirect']); } if ($this->fld_tags) { $this->addTables('tag_summary'); $this->addJoinConds(array('tag_summary' => array('LEFT JOIN', array('rc_id=ts_rc_id')))); $this->addFields('ts_tags'); } if ($this->fld_sha1) { $this->addTables('revision'); $this->addJoinConds(array('revision' => array('LEFT JOIN', array('rc_this_oldid=rev_id')))); $this->addFields(array('rev_sha1', 'rev_deleted')); } if ($params['toponly'] || $showRedirects) { $this->addTables('page'); $this->addJoinConds(array('page' => array('LEFT JOIN', array('rc_namespace=page_namespace', 'rc_title=page_title')))); $this->addFields('page_is_redirect'); if ($params['toponly']) { $this->addWhere('rc_this_oldid = page_latest'); } } if (!is_null($params['tag'])) { $this->addTables('change_tag'); $this->addJoinConds(array('change_tag' => array('INNER JOIN', array('rc_id=ct_rc_id')))); $this->addWhereFld('ct_tag', $params['tag']); } // Paranoia: avoid brute force searches (bug 17342) if (!is_null($params['user']) || !is_null($params['excludeuser'])) { if (!$user->isAllowed('deletedhistory')) { $bitmask = Revision::DELETED_USER; } elseif (!$user->isAllowedAny('suppressrevision', 'viewsuppressed')) { $bitmask = Revision::DELETED_USER | Revision::DELETED_RESTRICTED; } else { $bitmask = 0; } if ($bitmask) { $this->addWhere($this->getDB()->bitAnd('rc_deleted', $bitmask) . " != {$bitmask}"); } } if ($this->getRequest()->getCheck('namespace')) { // LogPage::DELETED_ACTION hides the affected page, too. if (!$user->isAllowed('deletedhistory')) { $bitmask = LogPage::DELETED_ACTION; } elseif (!$user->isAllowedAny('suppressrevision', 'viewsuppressed')) { $bitmask = LogPage::DELETED_ACTION | LogPage::DELETED_RESTRICTED; } else { $bitmask = 0; } if ($bitmask) { $this->addWhere($this->getDB()->makeList(array('rc_type != ' . RC_LOG, $this->getDB()->bitAnd('rc_deleted', $bitmask) . " != {$bitmask}"), LIST_OR)); } } $this->token = $params['token']; $this->addOption('LIMIT', $params['limit'] + 1); $this->addOption('USE INDEX', $index); $count = 0; /* Perform the actual query. */ $res = $this->select(__METHOD__); $titles = array(); $result = $this->getResult(); /* Iterate through the rows, adding data extracted from them to our query result. */ foreach ($res as $row) { if (++$count > $params['limit']) { // We've reached the one extra which shows that there are // additional pages to be had. Stop here... $this->setContinueEnumParameter('continue', "{$row->rc_timestamp}|{$row->rc_id}"); break; } if (is_null($resultPageSet)) { /* Extract the data from a single row. */ $vals = $this->extractRowInfo($row); /* Add that row's data to our final output. */ $fit = $result->addValue(array('query', $this->getModuleName()), null, $vals); if (!$fit) { $this->setContinueEnumParameter('continue', "{$row->rc_timestamp}|{$row->rc_id}"); break; } } else { $titles[] = Title::makeTitle($row->rc_namespace, $row->rc_title); } } if (is_null($resultPageSet)) { /* Format the result */ $result->addIndexedTagName(array('query', $this->getModuleName()), 'rc'); } else { $resultPageSet->populateFromTitles($titles); } }
public 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'); } }