Example #1
0
 /**
  * Patrols the article or provides the reason the patrol failed.
  */
 public function execute()
 {
     $params = $this->extractRequestParams();
     $this->requireOnlyOneParameter($params, 'rcid', 'revid');
     if (isset($params['rcid'])) {
         $rc = RecentChange::newFromID($params['rcid']);
         if (!$rc) {
             $this->dieUsageMsg(array('nosuchrcid', $params['rcid']));
         }
     } else {
         $rev = Revision::newFromId($params['revid']);
         if (!$rev) {
             $this->dieUsageMsg(array('nosuchrevid', $params['revid']));
         }
         $rc = $rev->getRecentChange();
         if (!$rc) {
             $this->dieUsage('The revision ' . $params['revid'] . " can't be patrolled as it's too old", 'notpatrollable');
         }
     }
     $retval = $rc->doMarkPatrolled($this->getUser());
     if ($retval) {
         $this->dieUsageMsg(reset($retval));
     }
     $result = array('rcid' => intval($rc->getAttribute('rc_id')));
     ApiQueryBase::addTitleInfo($result, $rc->getTitle());
     $this->getResult()->addValue(null, $this->getModuleName(), $result);
 }
Example #2
0
 /**
  * Purges the cache of a page
  */
 public function execute()
 {
     global $wgUser;
     $params = $this->extractRequestParams();
     if (!$wgUser->isAllowed('purge')) {
         $this->dieUsageMsg(array('cantpurge'));
     }
     if (!isset($params['titles'])) {
         $this->dieUsageMsg(array('missingparam', 'titles'));
     }
     $result = array();
     foreach ($params['titles'] as $t) {
         $r = array();
         $title = Title::newFromText($t);
         if (!$title instanceof Title) {
             $r['title'] = $t;
             $r['invalid'] = '';
             $result[] = $r;
             continue;
         }
         ApiQueryBase::addTitleInfo($r, $title);
         if (!$title->exists()) {
             $r['missing'] = '';
             $result[] = $r;
             continue;
         }
         $article = new Article($title);
         $article->doPurge();
         // Directly purge and skip the UI part of purge().
         $r['purged'] = '';
         $result[] = $r;
     }
     $this->getResult()->setIndexedTagName($result, 'page');
     $this->getResult()->addValue(null, $this->getModuleName(), $result);
 }
Example #3
0
 /**
  * Patrols the article or provides the reason the patrol failed.
  */
 public function execute()
 {
     global $wgUser, $wgUseRCPatrol, $wgUseNPPatrol;
     $this->getMain()->requestWriteMode();
     $params = $this->extractRequestParams();
     if (!isset($params['token'])) {
         $this->dieUsageMsg(array('missingparam', 'token'));
     }
     if (!isset($params['rcid'])) {
         $this->dieUsageMsg(array('missingparam', 'rcid'));
     }
     if (!$wgUser->matchEditToken($params['token'])) {
         $this->dieUsageMsg(array('sessionfailure'));
     }
     $rc = RecentChange::newFromID($params['rcid']);
     if (!$rc instanceof RecentChange) {
         $this->dieUsageMsg(array('nosuchrcid', $params['rcid']));
     }
     $retval = RecentChange::markPatrolled($params['rcid']);
     if ($retval) {
         $this->dieUsageMsg(current($retval));
     }
     $result = array('rcid' => $rc->getAttribute('rc_id'));
     ApiQueryBase::addTitleInfo($result, $rc->getTitle());
     $this->getResult()->addValue(null, $this->getModuleName(), $result);
 }
 /**
  * Purges the cache of a page
  */
 public function execute()
 {
     $params = $this->extractRequestParams();
     $forceLinkUpdate = $params['forcelinkupdate'];
     $pageSet = $this->getPageSet();
     $pageSet->execute();
     $result = array();
     self::addValues($result, $pageSet->getInvalidTitles(), 'invalid', 'title');
     self::addValues($result, $pageSet->getSpecialTitles(), 'special', 'title');
     self::addValues($result, $pageSet->getMissingPageIDs(), 'missing', 'pageid');
     self::addValues($result, $pageSet->getMissingRevisionIDs(), 'missing', 'revid');
     self::addValues($result, $pageSet->getMissingTitles(), 'missing');
     self::addValues($result, $pageSet->getInterwikiTitlesAsResult());
     foreach ($pageSet->getGoodTitles() as $title) {
         $r = array();
         ApiQueryBase::addTitleInfo($r, $title);
         $page = WikiPage::factory($title);
         $page->doPurge();
         // Directly purge and skip the UI part of purge().
         $r['purged'] = '';
         if ($forceLinkUpdate) {
             if (!$this->getUser()->pingLimiter()) {
                 global $wgEnableParserCache;
                 $popts = $page->makeParserOptions('canonical');
                 # Parse content; note that HTML generation is only needed if we want to cache the result.
                 $content = $page->getContent(Revision::RAW);
                 $p_result = $content->getParserOutput($title, $page->getLatest(), $popts, $wgEnableParserCache);
                 # Update the links tables
                 $updates = $content->getSecondaryDataUpdates($title, null, true, $p_result);
                 DataUpdate::runUpdates($updates);
                 $r['linkupdate'] = '';
                 if ($wgEnableParserCache) {
                     $pcache = ParserCache::singleton();
                     $pcache->save($p_result, $page, $popts);
                 }
             } else {
                 $error = $this->parseMsg(array('actionthrottledtext'));
                 $this->setWarning($error['info']);
                 $forceLinkUpdate = false;
             }
         }
         $result[] = $r;
     }
     $apiResult = $this->getResult();
     $apiResult->setIndexedTagName($result, 'page');
     $apiResult->addValue(null, $this->getModuleName(), $result);
     $values = $pageSet->getNormalizedTitlesAsResult($apiResult);
     if ($values) {
         $apiResult->addValue(null, 'normalized', $values);
     }
     $values = $pageSet->getConvertedTitlesAsResult($apiResult);
     if ($values) {
         $apiResult->addValue(null, 'converted', $values);
     }
     $values = $pageSet->getRedirectTitlesAsResult($apiResult);
     if ($values) {
         $apiResult->addValue(null, 'redirects', $values);
     }
 }
 public function __construct(ApiQuery $query, $moduleName, $prefix = 'ii')
 {
     // We allow a subclass to override the prefix, to create a related API
     // module. Some other parts of MediaWiki construct this with a null
     // $prefix, which used to be ignored when this only took two arguments
     if (is_null($prefix)) {
         $prefix = 'ii';
     }
     parent::__construct($query, $moduleName, $prefix);
 }
Example #6
0
 private function run($resultPageSet = null)
 {
     wfProfileIn($this->getModuleProfileName() . '-getDB');
     $db =& $this->getDB();
     wfProfileOut($this->getModuleProfileName() . '-getDB');
     wfProfileIn($this->getModuleProfileName() . '-parseParams');
     $limit = $from = $namespace = $filterredir = $prefix = null;
     extract($this->extractRequestParams());
     $this->addTables('page');
     if (!$this->addWhereIf('page_is_redirect = 1', $filterredir === 'redirects')) {
         $this->addWhereIf('page_is_redirect = 0', $filterredir === 'nonredirects');
     }
     $this->addWhereFld('page_namespace', $namespace);
     if (isset($from)) {
         $this->addWhere('page_title>=' . $db->addQuotes(ApiQueryBase::titleToKey($from)));
     }
     if (isset($prefix)) {
         $this->addWhere("page_title LIKE '{$db->strencode(ApiQueryBase::titleToKey($prefix))}%'");
     }
     if (is_null($resultPageSet)) {
         $this->addFields(array('page_id', 'page_namespace', 'page_title'));
     } else {
         $this->addFields($resultPageSet->getPageTableFields());
     }
     $this->addOption('USE INDEX', 'name_title');
     $this->addOption('LIMIT', $limit + 1);
     $this->addOption('ORDER BY', 'page_namespace, page_title');
     wfProfileOut($this->getModuleProfileName() . '-parseParams');
     $res = $this->select(__METHOD__);
     wfProfileIn($this->getModuleProfileName() . '-saveResults');
     $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('from', ApiQueryBase::keyToTitle($row->page_title));
             break;
         }
         if (is_null($resultPageSet)) {
             $vals = $this->addRowInfo('page', $row);
             if ($vals) {
                 $data[intval($row->page_id)] = $vals;
             }
         } else {
             $resultPageSet->processDbRow($row);
         }
     }
     $db->freeResult($res);
     if (is_null($resultPageSet)) {
         $result = $this->getResult();
         $result->setIndexedTagName($data, 'p');
         $result->addValue('query', $this->getModuleName(), $data);
     }
     wfProfileOut($this->getModuleProfileName() . '-saveResults');
 }
Example #7
0
 /**
  * Purges the cache of a page
  */
 public function execute()
 {
     global $wgUser;
     $params = $this->extractRequestParams();
     if (!$wgUser->isAllowed('purge') && !$this->getMain()->isInternalMode() && !$this->getMain()->getRequest()->wasPosted()) {
         $this->dieUsageMsg(array('mustbeposted', $this->getModuleName()));
     }
     $forceLinkUpdate = $params['forcelinkupdate'];
     $result = array();
     foreach ($params['titles'] as $t) {
         $r = array();
         $title = Title::newFromText($t);
         if (!$title instanceof Title) {
             $r['title'] = $t;
             $r['invalid'] = '';
             $result[] = $r;
             continue;
         }
         ApiQueryBase::addTitleInfo($r, $title);
         if (!$title->exists()) {
             $r['missing'] = '';
             $result[] = $r;
             continue;
         }
         $context = $this->createContext();
         $context->setTitle($title);
         $article = Article::newFromTitle($title, $context);
         $article->doPurge();
         // Directly purge and skip the UI part of purge().
         $r['purged'] = '';
         if ($forceLinkUpdate) {
             if (!$wgUser->pingLimiter()) {
                 global $wgParser, $wgEnableParserCache;
                 $popts = new ParserOptions();
                 $p_result = $wgParser->parse($article->getContent(), $title, $popts);
                 # Update the links tables
                 $u = new LinksUpdate($title, $p_result);
                 $u->doUpdate();
                 $r['linkupdate'] = '';
                 if ($wgEnableParserCache) {
                     $pcache = ParserCache::singleton();
                     $pcache->save($p_result, $article, $popts);
                 }
             } else {
                 $this->setWarning($this->parseMsg(array('actionthrottledtext')));
                 $forceLinkUpdate = false;
             }
         }
         $result[] = $r;
     }
     $apiResult = $this->getResult();
     $apiResult->setIndexedTagName($result, 'page');
     $apiResult->addValue(null, $this->getModuleName(), $result);
 }
Example #8
0
 private function run($resultPageSet = null)
 {
     $limit = $from = $namespace = $filterredir = null;
     extract($this->extractRequestParams());
     $db = $this->getDB();
     $where = array('page_namespace' => $namespace);
     if (isset($from)) {
         $where[] = 'page_title>=' . $db->addQuotes(ApiQueryBase::titleToKey($from));
     }
     if ($filterredir === 'redirects') {
         $where['page_is_redirect'] = 1;
     } elseif ($filterredir === 'nonredirects') {
         $where['page_is_redirect'] = 0;
     }
     if (is_null($resultPageSet)) {
         $fields = array('page_id', 'page_namespace', 'page_title');
     } else {
         $fields = $resultPageSet->getPageTableFields();
     }
     $this->profileDBIn();
     $res = $db->select('page', $fields, $where, __CLASS__ . '::' . __METHOD__, array('USE INDEX' => 'name_title', 'LIMIT' => $limit + 1, 'ORDER BY' => 'page_namespace, page_title'));
     $this->profileDBOut();
     $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...
             $msg = array('continue' => $this->encodeParamName('from') . '=' . ApiQueryBase::keyToTitle($row->page_title));
             $this->getResult()->addValue('query-status', 'allpages', $msg);
             break;
         }
         $title = Title::makeTitle($row->page_namespace, $row->page_title);
         // skip any pages that user has no rights to read
         if ($title->userCanRead()) {
             if (is_null($resultPageSet)) {
                 $id = intval($row->page_id);
                 $data[] = $id;
                 // in generator mode, just assemble a list of page IDs.
             } else {
                 $resultPageSet->processDbRow($row);
             }
         }
     }
     $db->freeResult($res);
     if (is_null($resultPageSet)) {
         ApiResult::setIndexedTagName($data, 'p');
         $this->getResult()->addValue('query', 'allpages', $data);
     }
 }
Example #9
0
 /**
  * Patrols the article or provides the reason the patrol failed.
  */
 public function execute()
 {
     $params = $this->extractRequestParams();
     $rc = RecentChange::newFromID($params['rcid']);
     if (!$rc instanceof RecentChange) {
         $this->dieUsageMsg(array('nosuchrcid', $params['rcid']));
     }
     $retval = $rc->doMarkPatrolled($this->getUser());
     if ($retval) {
         $this->dieUsageMsg(reset($retval));
     }
     $result = array('rcid' => intval($rc->getAttribute('rc_id')));
     ApiQueryBase::addTitleInfo($result, $rc->getTitle());
     $this->getResult()->addValue(null, $this->getModuleName(), $result);
 }
Example #10
0
 public function __construct($query, $resolveRedirects = false)
 {
     parent::__construct($query, __CLASS__);
     $this->mAllPages = array();
     $this->mGoodTitles = array();
     $this->mMissingTitles = array();
     $this->mMissingPageIDs = array();
     $this->mRedirectTitles = array();
     $this->mNormalizedTitles = array();
     $this->mRequestedPageFields = array();
     $this->mResolveRedirects = $resolveRedirects;
     if ($resolveRedirects) {
         $this->mPendingRedirectIDs = array();
     }
 }
 private function run($resultPageSet = null)
 {
     $db = $this->getDB();
     $params = $this->extractRequestParams();
     $this->addTables('page');
     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'])) . "%'");
     }
     if (is_null($resultPageSet)) {
         $this->addFields(array('page_id', 'page_namespace', 'page_title'));
     } else {
         $this->addFields($resultPageSet->getPageTableFields());
     }
     $this->addOption('USE INDEX', 'name_title');
     $limit = $params['limit'];
     $this->addOption('LIMIT', $limit + 1);
     $this->addOption('ORDER BY', 'page_namespace, page_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->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);
     }
 }
Example #12
0
 /**
  * Add all items from $values into the result
  * @param array $result Output
  * @param array $values Values to add
  * @param string $flag The name of the boolean flag to mark this element
  * @param string $name If given, name of the value
  */
 private static function addValues(array &$result, $values, $flag = null, $name = null)
 {
     foreach ($values as $val) {
         if ($val instanceof Title) {
             $v = array();
             ApiQueryBase::addTitleInfo($v, $val);
         } elseif ($name !== null) {
             $v = array($name => $val);
         } else {
             $v = $val;
         }
         if ($flag !== null) {
             $v[$flag] = '';
         }
         $result[] = $v;
     }
 }
	function reportPage( $title, $origTitle, $revisionCount, $successCount, $pageInfo = '' ) {
		// Add a result entry
		$r = array();
		ApiQueryBase::addTitleInfo($r, $title);
		$r['revisions'] = intval($successCount);
		$this->mResultArr[] = $r;

		# call the parent to do the logging
		# avoid bug in 1.15.4 Special:Import (new file page text without the file uploaded)
		# PHP Fatal error:  Call to a member function insertOn() on a non-object in E:\www\psychologos\includes\specials\SpecialImport.php on line 334
		// do not create informational null revisions
		// because they are placed on top of real user made revisions,
		// making the binary search algorithm used to compare local and remote revs to fail
		// TODO: change the binary search algorithm to two/three level hashes
		if ( WikiSyncSetup::$report_null_revisions && $title->getArticleId() !== 0 ) {
			parent::reportPage( $title, $origTitle, $revisionCount, $successCount, $pageInfo );
		}
	}
Example #14
0
 private function run($resultPageSet = null)
 {
     $db = $this->getDB();
     $params = $this->extractRequestParams();
     $this->addTables('categorylinks');
     $this->addFields('cl_to');
     if (!is_null($params['from'])) {
         $this->addWhere('cl_to>=' . $db->addQuotes(ApiQueryBase::titleToKey($params['from'])));
     }
     if (isset($params['prefix'])) {
         $this->addWhere("cl_to LIKE '" . $db->escapeLike(ApiQueryBase::titleToKey($params['prefix'])) . "%'");
     }
     $this->addOption('LIMIT', $params['limit'] + 1);
     $this->addOption('ORDER BY', 'cl_to' . ($params['dir'] == 'descending' ? ' DESC' : ''));
     $this->addOption('DISTINCT');
     $res = $this->select(__METHOD__);
     $pages = array();
     $count = 0;
     while ($row = $db->fetchObject($res)) {
         if (++$count > $params['limit']) {
             // We've reached the one extra which shows that there are additional cats 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->cl_to));
             break;
         }
         // Normalize titles
         $titleObj = Title::makeTitle(NS_CATEGORY, $row->cl_to);
         if (!is_null($resultPageSet)) {
             $pages[] = $titleObj->getPrefixedText();
         } else {
             // Don't show "Category:" everywhere in non-generator mode
             $pages[] = $titleObj->getText();
         }
     }
     $db->freeResult($res);
     if (is_null($resultPageSet)) {
         $result = $this->getResult();
         $result->setIndexedTagName($pages, 'c');
         $result->addValue('query', $this->getModuleName(), $pages);
     } else {
         $resultPageSet->populateFromTitles($pages);
     }
 }
Example #15
0
 /**
  * Constructor
  * @param $query ApiQuery
  * @param $resolveRedirects bool Whether redirects should be resolved
  */
 public function __construct($query, $resolveRedirects = false)
 {
     parent::__construct($query, 'query');
     $this->mAllPages = array();
     $this->mTitles = array();
     $this->mGoodTitles = array();
     $this->mMissingTitles = array();
     $this->mInvalidTitles = array();
     $this->mMissingPageIDs = array();
     $this->mRedirectTitles = array();
     $this->mNormalizedTitles = array();
     $this->mInterwikiTitles = array();
     $this->mGoodRevIDs = array();
     $this->mMissingRevIDs = array();
     $this->mRequestedPageFields = array();
     $this->mResolveRedirects = $resolveRedirects;
     if ($resolveRedirects) {
         $this->mPendingRedirectIDs = array();
     }
     $this->mFakePageId = -1;
 }
 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);
 }
Example #17
0
 /**
  * Patrols the article or provides the reason the patrol failed.
  */
 public function execute()
 {
     $params = $this->extractRequestParams();
     $this->requireOnlyOneParameter($params, 'rcid', 'revid');
     if (isset($params['rcid'])) {
         $rc = RecentChange::newFromId($params['rcid']);
         if (!$rc) {
             $this->dieUsageMsg(['nosuchrcid', $params['rcid']]);
         }
     } else {
         $rev = Revision::newFromId($params['revid']);
         if (!$rev) {
             $this->dieUsageMsg(['nosuchrevid', $params['revid']]);
         }
         $rc = $rev->getRecentChange();
         if (!$rc) {
             $this->dieUsage('The revision ' . $params['revid'] . " can't be patrolled as it's too old", 'notpatrollable');
         }
     }
     $user = $this->getUser();
     $tags = $params['tags'];
     // Check if user can add tags
     if (!is_null($tags)) {
         $ableToTag = ChangeTags::canAddTagsAccompanyingChange($tags, $user);
         if (!$ableToTag->isOK()) {
             $this->dieStatus($ableToTag);
         }
     }
     $retval = $rc->doMarkPatrolled($user, false, $tags);
     if ($retval) {
         $this->dieUsageMsg(reset($retval));
     }
     $result = ['rcid' => intval($rc->getAttribute('rc_id'))];
     ApiQueryBase::addTitleInfo($result, $rc->getTitle());
     $this->getResult()->addValue(null, $this->getModuleName(), $result);
 }
Example #18
0
 /**
  * Overrides base class to prepend 'g' to every generator parameter
  * @param $paramName string Parameter name
  * @return string Prefixed parameter name
  */
 public function encodeParamName($paramName)
 {
     if ($this->mIsGenerator) {
         return 'g' . parent::encodeParamName($paramName);
     } else {
         return parent::encodeParamName($paramName);
     }
 }
 /**
  * @param $resultPageSet ApiPageSet
  * @return void
  */
 private function run($resultPageSet = null)
 {
     $params = $this->extractRequestParams();
     $this->addTables('protected_titles');
     $this->addFields(array('pt_namespace', 'pt_title', 'pt_timestamp'));
     $prop = array_flip($params['prop']);
     $this->addFieldsIf('pt_user', isset($prop['user']) || isset($prop['userid']));
     $this->addFieldsIf('pt_reason', isset($prop['comment']) || isset($prop['parsedcomment']));
     $this->addFieldsIf('pt_expiry', isset($prop['expiry']));
     $this->addFieldsIf('pt_create_perm', isset($prop['level']));
     $this->addTimestampWhereRange('pt_timestamp', $params['dir'], $params['start'], $params['end']);
     $this->addWhereFld('pt_namespace', $params['namespace']);
     $this->addWhereFld('pt_create_perm', $params['level']);
     if (isset($prop['user'])) {
         $this->addTables('user');
         $this->addFields('user_name');
         $this->addJoinConds(array('user' => array('LEFT JOIN', 'user_id=pt_user')));
     }
     $this->addOption('LIMIT', $params['limit'] + 1);
     $res = $this->select(__METHOD__);
     $count = 0;
     $result = $this->getResult();
     $titles = array();
     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('start', wfTimestamp(TS_ISO_8601, $row->pt_timestamp));
             break;
         }
         $title = Title::makeTitle($row->pt_namespace, $row->pt_title);
         if (is_null($resultPageSet)) {
             $vals = array();
             ApiQueryBase::addTitleInfo($vals, $title);
             if (isset($prop['timestamp'])) {
                 $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->pt_timestamp);
             }
             if (isset($prop['user']) && !is_null($row->user_name)) {
                 $vals['user'] = $row->user_name;
             }
             if (isset($prop['user'])) {
                 $vals['userid'] = $row->pt_user;
             }
             if (isset($prop['comment'])) {
                 $vals['comment'] = $row->pt_reason;
             }
             if (isset($prop['parsedcomment'])) {
                 global $wgUser;
                 $vals['parsedcomment'] = $wgUser->getSkin()->formatComment($row->pt_reason, $title);
             }
             if (isset($prop['expiry'])) {
                 global $wgContLang;
                 $vals['expiry'] = $wgContLang->formatExpiry($row->pt_expiry, TS_ISO_8601);
             }
             if (isset($prop['level'])) {
                 $vals['level'] = $row->pt_create_perm;
             }
             $fit = $result->addValue(array('query', $this->getModuleName()), null, $vals);
             if (!$fit) {
                 $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->pt_timestamp));
                 break;
             }
         } else {
             $titles[] = $title;
         }
     }
     if (is_null($resultPageSet)) {
         $result->setIndexedTagName_internal(array('query', $this->getModuleName()), $this->getModulePrefix());
     } else {
         $resultPageSet->populateFromTitles($titles);
     }
 }
Example #20
0
 private function run($resultPageSet = null)
 {
     if ($this->getPageSet()->getGoodTitleCount() == 0) {
         return;
     }
     // nothing to do
     $params = $this->extractRequestParams();
     $prop = array_flip((array) $params['prop']);
     $show = array_flip((array) $params['show']);
     $this->addFields(array('cl_from', 'cl_to'));
     $this->addFieldsIf('cl_sortkey', isset($prop['sortkey']));
     $this->addFieldsIf('cl_timestamp', isset($prop['timestamp']));
     $this->addTables('categorylinks');
     $this->addWhereFld('cl_from', array_keys($this->getPageSet()->getGoodTitles()));
     if (!is_null($params['categories'])) {
         $cats = array();
         foreach ($params['categories'] as $cat) {
             $title = Title::newFromText($cat);
             if (!$title || $title->getNamespace() != NS_CATEGORY) {
                 $this->setWarning("``{$cat}'' is not a category");
             } else {
                 $cats[] = $title->getDBkey();
             }
         }
         $this->addWhereFld('cl_to', $cats);
     }
     if (!is_null($params['continue'])) {
         $cont = explode('|', $params['continue']);
         if (count($cont) != 2) {
             $this->dieUsage("Invalid continue param. You should pass the " . "original value returned by the previous query", "_badcontinue");
         }
         $clfrom = intval($cont[0]);
         $clto = $this->getDB()->strencode($this->titleToKey($cont[1]));
         $this->addWhere("cl_from > {$clfrom} OR " . "(cl_from = {$clfrom} AND " . "cl_to >= '{$clto}')");
     }
     if (isset($show['hidden']) && isset($show['!hidden'])) {
         $this->dieUsageMsg(array('show'));
     }
     if (isset($show['hidden']) || isset($show['!hidden']) || isset($prop['hidden'])) {
         $this->addOption('STRAIGHT_JOIN');
         $this->addTables(array('page', 'page_props'));
         $this->addFieldsIf('pp_propname', isset($prop['hidden']));
         $this->addJoinConds(array('page' => array('LEFT JOIN', array('page_namespace' => NS_CATEGORY, 'page_title = cl_to')), 'page_props' => array('LEFT JOIN', array('pp_page=page_id', 'pp_propname' => 'hiddencat'))));
         if (isset($show['hidden'])) {
             $this->addWhere(array('pp_propname IS NOT NULL'));
         } else {
             if (isset($show['!hidden'])) {
                 $this->addWhere(array('pp_propname IS NULL'));
             }
         }
     }
     $this->addOption('USE INDEX', array('categorylinks' => 'cl_from'));
     // Don't order by cl_from if it's constant in the WHERE clause
     if (count($this->getPageSet()->getGoodTitles()) == 1) {
         $this->addOption('ORDER BY', 'cl_to');
     } else {
         $this->addOption('ORDER BY', "cl_from, cl_to");
     }
     $db = $this->getDB();
     $res = $this->select(__METHOD__);
     if (is_null($resultPageSet)) {
         $count = 0;
         while ($row = $db->fetchObject($res)) {
             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->cl_from . '|' . $this->keyToTitle($row->cl_to));
                 break;
             }
             $title = Title::makeTitle(NS_CATEGORY, $row->cl_to);
             $vals = array();
             ApiQueryBase::addTitleInfo($vals, $title);
             if (isset($prop['sortkey'])) {
                 $vals['sortkey'] = $row->cl_sortkey;
             }
             if (isset($prop['timestamp'])) {
                 $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->cl_timestamp);
             }
             if (isset($prop['hidden']) && !is_null($row->pp_propname)) {
                 $vals['hidden'] = '';
             }
             $fit = $this->addPageSubItem($row->cl_from, $vals);
             if (!$fit) {
                 $this->setContinueEnumParameter('continue', $row->cl_from . '|' . $this->keyToTitle($row->cl_to));
                 break;
             }
         }
     } else {
         $titles = array();
         while ($row = $db->fetchObject($res)) {
             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->cl_from . '|' . $this->keyToTitle($row->cl_to));
                 break;
             }
             $titles[] = Title::makeTitle(NS_CATEGORY, $row->cl_to);
         }
         $resultPageSet->populateFromTitles($titles);
     }
     $db->freeResult($res);
 }
 public function __construct(ApiQuery $query, $moduleName)
 {
     parent::__construct($query, $moduleName, 'fri');
 }
Example #22
0
 private function extractRowInfo($row)
 {
     $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_EXTERNAL:
             $vals['type'] = 'external';
             break;
         case RC_MOVE_OVER_REDIRECT:
             $vals['type'] = 'move over redirect';
             break;
         default:
             $vals['type'] = $type;
     }
     if ($this->fld_ids) {
         $vals['pageid'] = intval($row->rc_cur_id);
         $vals['revid'] = intval($row->rc_this_oldid);
         $vals['old_revid'] = intval($row->rc_last_oldid);
     }
     $title = Title::makeTitle($row->rc_namespace, $row->rc_title);
     if ($this->fld_title) {
         ApiQueryBase::addTitleInfo($vals, $title);
     }
     if ($this->fld_user || $this->fld_userid) {
         if ($this->fld_userid) {
             $vals['userid'] = $row->rc_user;
             // for backwards compatibility
             $vals['user'] = $row->rc_user;
         }
         if ($this->fld_user) {
             $vals['user'] = $row->rc_user_text;
         }
         if (!$row->rc_user) {
             $vals['anon'] = '';
         }
     }
     if ($this->fld_flags) {
         if ($row->rc_type == RC_NEW) {
             $vals['new'] = '';
         }
         if ($row->rc_minor) {
             $vals['minor'] = '';
         }
         if ($row->rc_bot) {
             $vals['bot'] = '';
         }
     }
     if ($this->fld_patrol && isset($row->rc_patrolled)) {
         $vals['patrolled'] = '';
     }
     if ($this->fld_timestamp) {
         $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->rc_timestamp);
     }
     if ($this->fld_sizes) {
         $vals['oldlen'] = intval($row->rc_old_len);
         $vals['newlen'] = intval($row->rc_new_len);
     }
     if ($this->fld_notificationtimestamp) {
         $vals['notificationtimestamp'] = $row->wl_notificationtimestamp == null ? '' : wfTimestamp(TS_ISO_8601, $row->wl_notificationtimestamp);
     }
     if ($this->fld_comment && isset($row->rc_comment)) {
         $vals['comment'] = $row->rc_comment;
     }
     if ($this->fld_parsedcomment && isset($row->rc_comment)) {
         $vals['parsedcomment'] = Linker::formatComment($row->rc_comment, $title);
     }
     if ($this->fld_loginfo && $row->rc_type == RC_LOG) {
         $vals['logid'] = intval($row->rc_logid);
         $vals['logtype'] = $row->rc_log_type;
         $vals['logaction'] = $row->rc_log_action;
         $logEntry = DatabaseLogEntry::newFromRow((array) $row);
         ApiQueryLogEvents::addLogParams($this->getResult(), $vals, $logEntry->getParameters(), $logEntry->getType(), $logEntry->getSubtype(), $logEntry->getTimestamp());
     }
     return $vals;
 }
 /**
  * Extracts from a single sql row the data needed to describe one recent change.
  *
  * @param stdClass $row The row from which to extract the data.
  * @return array An array mapping strings (descriptors) to their respective string values.
  * @access public
  */
 public function extractRowInfo($row)
 {
     /* Determine the title of the page that has been changed. */
     $title = Title::makeTitle($row->rc_namespace, $row->rc_title);
     $user = $this->getUser();
     /* Our output data. */
     $vals = array();
     $type = intval($row->rc_type);
     $vals['type'] = RecentChange::parseFromRCType($type);
     $anyHidden = false;
     /* Create a new entry in the result for the title. */
     if ($this->fld_title || $this->fld_ids) {
         if ($type === RC_LOG && $row->rc_deleted & LogPage::DELETED_ACTION) {
             $vals['actionhidden'] = true;
             $anyHidden = true;
         }
         if ($type !== RC_LOG || LogEventsList::userCanBitfield($row->rc_deleted, LogPage::DELETED_ACTION, $user)) {
             if ($this->fld_title) {
                 ApiQueryBase::addTitleInfo($vals, $title);
             }
             if ($this->fld_ids) {
                 $vals['pageid'] = intval($row->rc_cur_id);
                 $vals['revid'] = intval($row->rc_this_oldid);
                 $vals['old_revid'] = intval($row->rc_last_oldid);
             }
         }
     }
     if ($this->fld_ids) {
         $vals['rcid'] = intval($row->rc_id);
     }
     /* Add user data and 'anon' flag, if user is anonymous. */
     if ($this->fld_user || $this->fld_userid) {
         if ($row->rc_deleted & Revision::DELETED_USER) {
             $vals['userhidden'] = true;
             $anyHidden = true;
         }
         if (Revision::userCanBitfield($row->rc_deleted, Revision::DELETED_USER, $user)) {
             if ($this->fld_user) {
                 $vals['user'] = $row->rc_user_text;
             }
             if ($this->fld_userid) {
                 $vals['userid'] = $row->rc_user;
             }
             if (!$row->rc_user) {
                 $vals['anon'] = true;
             }
         }
     }
     /* Add flags, such as new, minor, bot. */
     if ($this->fld_flags) {
         $vals['bot'] = (bool) $row->rc_bot;
         $vals['new'] = $row->rc_type == RC_NEW;
         $vals['minor'] = (bool) $row->rc_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 || $this->fld_parsedcomment) {
         if ($row->rc_deleted & Revision::DELETED_COMMENT) {
             $vals['commenthidden'] = true;
             $anyHidden = true;
         }
         if (Revision::userCanBitfield($row->rc_deleted, Revision::DELETED_COMMENT, $user)) {
             if ($this->fld_comment && isset($row->rc_comment)) {
                 $vals['comment'] = $row->rc_comment;
             }
             if ($this->fld_parsedcomment && isset($row->rc_comment)) {
                 $vals['parsedcomment'] = Linker::formatComment($row->rc_comment, $title);
             }
         }
     }
     if ($this->fld_redirect) {
         $vals['redirect'] = (bool) $row->page_is_redirect;
     }
     /* Add the patrolled flag */
     if ($this->fld_patrolled) {
         $vals['patrolled'] = $row->rc_patrolled == 1;
         $vals['unpatrolled'] = ChangesList::isUnpatrolled($row, $user);
     }
     if ($this->fld_loginfo && $row->rc_type == RC_LOG) {
         if ($row->rc_deleted & LogPage::DELETED_ACTION) {
             $vals['actionhidden'] = true;
             $anyHidden = true;
         }
         if (LogEventsList::userCanBitfield($row->rc_deleted, LogPage::DELETED_ACTION, $user)) {
             $vals['logid'] = intval($row->rc_logid);
             $vals['logtype'] = $row->rc_log_type;
             $vals['logaction'] = $row->rc_log_action;
             $vals['logparams'] = LogFormatter::newFromRow($row)->formatParametersForApi();
         }
     }
     if ($this->fld_tags) {
         if ($row->ts_tags) {
             $tags = explode(',', $row->ts_tags);
             ApiResult::setIndexedTagName($tags, 'tag');
             $vals['tags'] = $tags;
         } else {
             $vals['tags'] = array();
         }
     }
     if ($this->fld_sha1 && $row->rev_sha1 !== null) {
         if ($row->rev_deleted & Revision::DELETED_TEXT) {
             $vals['sha1hidden'] = true;
             $anyHidden = true;
         }
         if (Revision::userCanBitfield($row->rev_deleted, Revision::DELETED_TEXT, $user)) {
             if ($row->rev_sha1 !== '') {
                 $vals['sha1'] = wfBaseConvert($row->rev_sha1, 36, 16, 40);
             } else {
                 $vals['sha1'] = '';
             }
         }
     }
     if (!is_null($this->token)) {
         $tokenFunctions = $this->getTokenFunctions();
         foreach ($this->token as $t) {
             $val = call_user_func($tokenFunctions[$t], $row->rc_cur_id, $title, RecentChange::newFromRow($row));
             if ($val === false) {
                 $this->setWarning("Action '{$t}' is not allowed for the current user");
             } else {
                 $vals[$t . 'token'] = $val;
             }
         }
     }
     if ($anyHidden && $row->rc_deleted & Revision::DELETED_RESTRICTED) {
         $vals['suppressed'] = true;
     }
     return $vals;
 }
 /**
  * @param $resultPageSet ApiPageSet
  * @return void
  */
 private function run($resultPageSet = null)
 {
     $this->selectNamedDB('watchlist', DB_SLAVE, 'watchlist');
     $params = $this->extractRequestParams();
     $user = $this->getWatchlistUser($params);
     $prop = array_flip((array) $params['prop']);
     $show = array_flip((array) $params['show']);
     if (isset($show['changed']) && isset($show['!changed'])) {
         $this->dieUsageMsg('show');
     }
     $this->addTables('watchlist');
     $this->addFields(array('wl_namespace', 'wl_title'));
     $this->addFieldsIf('wl_notificationtimestamp', isset($prop['changed']));
     $this->addWhereFld('wl_user', $user->getId());
     $this->addWhereFld('wl_namespace', $params['namespace']);
     $this->addWhereIf('wl_notificationtimestamp IS NOT NULL', isset($show['changed']));
     $this->addWhereIf('wl_notificationtimestamp IS NULL', isset($show['!changed']));
     if (isset($params['continue'])) {
         $cont = explode('|', $params['continue']);
         $this->dieContinueUsageIf(count($cont) != 2);
         $ns = intval($cont[0]);
         $this->dieContinueUsageIf(strval($ns) !== $cont[0]);
         $title = $this->getDB()->addQuotes($cont[1]);
         $op = $params['dir'] == 'ascending' ? '>' : '<';
         $this->addWhere("wl_namespace {$op} {$ns} OR " . "(wl_namespace = {$ns} AND " . "wl_title {$op}= {$title})");
     }
     $sort = $params['dir'] == 'descending' ? ' DESC' : '';
     // Don't ORDER BY wl_namespace if it's constant in the WHERE clause
     if (count($params['namespace']) == 1) {
         $this->addOption('ORDER BY', 'wl_title' . $sort);
     } else {
         $this->addOption('ORDER BY', array('wl_namespace' . $sort, 'wl_title' . $sort));
     }
     $this->addOption('LIMIT', $params['limit'] + 1);
     $res = $this->select(__METHOD__);
     $titles = array();
     $count = 0;
     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->wl_namespace . '|' . $row->wl_title);
             break;
         }
         $t = Title::makeTitle($row->wl_namespace, $row->wl_title);
         if (is_null($resultPageSet)) {
             $vals = array();
             ApiQueryBase::addTitleInfo($vals, $t);
             if (isset($prop['changed']) && !is_null($row->wl_notificationtimestamp)) {
                 $vals['changed'] = wfTimestamp(TS_ISO_8601, $row->wl_notificationtimestamp);
             }
             $fit = $this->getResult()->addValue($this->getModuleName(), null, $vals);
             if (!$fit) {
                 $this->setContinueEnumParameter('continue', $row->wl_namespace . '|' . $row->wl_title);
                 break;
             }
         } else {
             $titles[] = $t;
         }
     }
     if (is_null($resultPageSet)) {
         $this->getResult()->setIndexedTagName_internal($this->getModuleName(), 'wr');
     } else {
         $resultPageSet->populateFromTitles($titles);
     }
 }
Example #25
0
 /**
  * Appends an element for each page in the current pageSet with the
  * most general information (id, title), plus any title normalizations
  * and missing or invalid title/pageids/revids.
  */
 private function outputGeneralPageInfo()
 {
     $pageSet = $this->getPageSet();
     $result = $this->getResult();
     // We don't check for a full result set here because we can't be adding
     // more than 380K. The maximum revision size is in the megabyte range,
     // and the maximum result size must be even higher than that.
     $values = $pageSet->getNormalizedTitlesAsResult($result);
     if ($values) {
         $result->addValue('query', 'normalized', $values);
     }
     $values = $pageSet->getConvertedTitlesAsResult($result);
     if ($values) {
         $result->addValue('query', 'converted', $values);
     }
     $values = $pageSet->getInterwikiTitlesAsResult($result, $this->mParams['iwurl']);
     if ($values) {
         $result->addValue('query', 'interwiki', $values);
     }
     $values = $pageSet->getRedirectTitlesAsResult($result);
     if ($values) {
         $result->addValue('query', 'redirects', $values);
     }
     $values = $pageSet->getMissingRevisionIDsAsResult($result);
     if ($values) {
         $result->addValue('query', 'badrevids', $values);
     }
     // 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 invalid titles
     foreach ($pageSet->getInvalidTitles() as $fakeId => $title) {
         $pages[$fakeId] = array('title' => $title, 'invalid' => '');
     }
     // Report any missing page ids
     foreach ($pageSet->getMissingPageIDs() as $pageid) {
         $pages[$pageid] = array('pageid' => $pageid, 'missing' => '');
     }
     // Report special pages
     /** @var $title Title */
     foreach ($pageSet->getSpecialTitles() as $fakeId => $title) {
         $vals = array();
         ApiQueryBase::addTitleInfo($vals, $title);
         $vals['special'] = '';
         if ($title->isSpecialPage() && !SpecialPageFactory::exists($title->getDBkey())) {
             $vals['missing'] = '';
         } elseif ($title->getNamespace() == NS_MEDIA && !wfFindFile($title)) {
             $vals['missing'] = '';
         }
         $pages[$fakeId] = $vals;
     }
     // 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 (count($pages)) {
         if ($this->mParams['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);
     }
     if ($this->mParams['export']) {
         $this->doExport($pageSet, $result);
     }
 }
Example #26
0
 /**
  * @param ApiPageSet $resultPageSet
  */
 private function run($resultPageSet = null)
 {
     if ($this->getPageSet()->getGoodTitleCount() == 0) {
         return;
         // nothing to do
     }
     $params = $this->extractRequestParams();
     $prop = array_flip((array) $params['prop']);
     $show = array_flip((array) $params['show']);
     $this->addFields(array('cl_from', 'cl_to'));
     $this->addFieldsIf(array('cl_sortkey', 'cl_sortkey_prefix'), isset($prop['sortkey']));
     $this->addFieldsIf('cl_timestamp', isset($prop['timestamp']));
     $this->addTables('categorylinks');
     $this->addWhereFld('cl_from', array_keys($this->getPageSet()->getGoodTitles()));
     if (!is_null($params['categories'])) {
         $cats = array();
         foreach ($params['categories'] as $cat) {
             $title = Title::newFromText($cat);
             if (!$title || $title->getNamespace() != NS_CATEGORY) {
                 $this->setWarning("\"{$cat}\" is not a category");
             } else {
                 $cats[] = $title->getDBkey();
             }
         }
         $this->addWhereFld('cl_to', $cats);
     }
     if (!is_null($params['continue'])) {
         $cont = explode('|', $params['continue']);
         $this->dieContinueUsageIf(count($cont) != 2);
         $op = $params['dir'] == 'descending' ? '<' : '>';
         $clfrom = intval($cont[0]);
         $clto = $this->getDB()->addQuotes($cont[1]);
         $this->addWhere("cl_from {$op} {$clfrom} OR " . "(cl_from = {$clfrom} AND " . "cl_to {$op}= {$clto})");
     }
     if (isset($show['hidden']) && isset($show['!hidden'])) {
         $this->dieUsageMsg('show');
     }
     if (isset($show['hidden']) || isset($show['!hidden']) || isset($prop['hidden'])) {
         $this->addOption('STRAIGHT_JOIN');
         $this->addTables(array('page', 'page_props'));
         $this->addFieldsIf('pp_propname', isset($prop['hidden']));
         $this->addJoinConds(array('page' => array('LEFT JOIN', array('page_namespace' => NS_CATEGORY, 'page_title = cl_to')), 'page_props' => array('LEFT JOIN', array('pp_page=page_id', 'pp_propname' => 'hiddencat'))));
         if (isset($show['hidden'])) {
             $this->addWhere(array('pp_propname IS NOT NULL'));
         } elseif (isset($show['!hidden'])) {
             $this->addWhere(array('pp_propname IS NULL'));
         }
     }
     $sort = $params['dir'] == 'descending' ? ' DESC' : '';
     // Don't order by cl_from if it's constant in the WHERE clause
     if (count($this->getPageSet()->getGoodTitles()) == 1) {
         $this->addOption('ORDER BY', 'cl_to' . $sort);
     } else {
         $this->addOption('ORDER BY', array('cl_from' . $sort, 'cl_to' . $sort));
     }
     $res = $this->select(__METHOD__);
     $count = 0;
     if (is_null($resultPageSet)) {
         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->cl_from . '|' . $row->cl_to);
                 break;
             }
             $title = Title::makeTitle(NS_CATEGORY, $row->cl_to);
             $vals = array();
             ApiQueryBase::addTitleInfo($vals, $title);
             if (isset($prop['sortkey'])) {
                 $vals['sortkey'] = bin2hex($row->cl_sortkey);
                 $vals['sortkeyprefix'] = $row->cl_sortkey_prefix;
             }
             if (isset($prop['timestamp'])) {
                 $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->cl_timestamp);
             }
             if (isset($prop['hidden'])) {
                 $vals['hidden'] = !is_null($row->pp_propname);
             }
             $fit = $this->addPageSubItem($row->cl_from, $vals);
             if (!$fit) {
                 $this->setContinueEnumParameter('continue', $row->cl_from . '|' . $row->cl_to);
                 break;
             }
         }
     } else {
         $titles = array();
         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->cl_from . '|' . $row->cl_to);
                 break;
             }
             $titles[] = Title::makeTitle(NS_CATEGORY, $row->cl_to);
         }
         $resultPageSet->populateFromTitles($titles);
     }
 }
 public function __construct($query, $moduleName)
 {
     parent::__construct($query, $moduleName, 'mt');
 }
 /**
  * @param ApiPageSet $resultPageSet
  * @return void
  */
 protected function run(ApiPageSet $resultPageSet = null)
 {
     $db = $this->getDB();
     $params = $this->extractRequestParams(false);
     $result = $this->getResult();
     $this->requireMaxOneParameter($params, 'user', 'excludeuser');
     // Namespace check is likely to be desired, but can't be done
     // efficiently in SQL.
     $miser_ns = null;
     $needPageTable = false;
     if ($params['namespace'] !== null) {
         $params['namespace'] = array_unique($params['namespace']);
         sort($params['namespace']);
         if ($params['namespace'] != MWNamespace::getValidNamespaces()) {
             $needPageTable = true;
             if ($this->getConfig()->get('MiserMode')) {
                 $miser_ns = $params['namespace'];
             } else {
                 $this->addWhere(array('page_namespace' => $params['namespace']));
             }
         }
     }
     $this->addTables('revision');
     if ($resultPageSet === null) {
         $this->parseParameters($params);
         $this->addTables('page');
         $this->addJoinConds(array('page' => array('INNER JOIN', array('rev_page = page_id'))));
         $this->addFields(Revision::selectFields());
         $this->addFields(Revision::selectPageFields());
         // Review this depeneding on the outcome of T113901
         $this->addOption('STRAIGHT_JOIN');
     } else {
         $this->limit = $this->getParameter('limit') ?: 10;
         $this->addFields(array('rev_timestamp', 'rev_id'));
         if ($params['generatetitles']) {
             $this->addFields(array('rev_page'));
         }
         if ($needPageTable) {
             $this->addTables('page');
             $this->addJoinConds(array('page' => array('INNER JOIN', array('rev_page = page_id'))));
             $this->addFieldsIf(array('page_namespace'), (bool) $miser_ns);
             // Review this depeneding on the outcome of T113901
             $this->addOption('STRAIGHT_JOIN');
         }
     }
     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 ($this->fetchContent) {
         $this->addTables('text');
         $this->addJoinConds(array('text' => array('INNER JOIN', array('rev_text_id=old_id'))));
         $this->addFields('old_id');
         $this->addFields(Revision::selectTextFields());
     }
     if ($params['user'] !== null) {
         $id = User::idFromName($params['user']);
         if ($id) {
             $this->addWhereFld('rev_user', $id);
         } else {
             $this->addWhereFld('rev_user_text', $params['user']);
         }
     } elseif ($params['excludeuser'] !== null) {
         $id = User::idFromName($params['excludeuser']);
         if ($id) {
             $this->addWhere('rev_user != ' . $id);
         } else {
             $this->addWhere('rev_user_text != ' . $db->addQuotes($params['excludeuser']));
         }
     }
     if ($params['user'] !== null || $params['excludeuser'] !== null) {
         // 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}");
         }
     }
     $dir = $params['dir'];
     if ($params['continue'] !== null) {
         $op = $dir == 'newer' ? '>' : '<';
         $cont = explode('|', $params['continue']);
         $this->dieContinueUsageIf(count($cont) != 2);
         $ts = $db->addQuotes($db->timestamp($cont[0]));
         $rev_id = (int) $cont[1];
         $this->dieContinueUsageIf(strval($rev_id) !== $cont[1]);
         $this->addWhere("rev_timestamp {$op} {$ts} OR " . "(rev_timestamp = {$ts} AND " . "rev_id {$op}= {$rev_id})");
     }
     $this->addOption('LIMIT', $this->limit + 1);
     $sort = $dir == 'newer' ? '' : ' DESC';
     $orderby = array();
     // Targeting index rev_timestamp, user_timestamp, or usertext_timestamp
     // But 'user' is always constant for the latter two, so it doesn't matter here.
     $orderby[] = "rev_timestamp {$sort}";
     $orderby[] = "rev_id {$sort}";
     $this->addOption('ORDER BY', $orderby);
     $res = $this->select(__METHOD__);
     $pageMap = array();
     // Maps rev_page to array index
     $count = 0;
     $nextIndex = 0;
     $generated = array();
     foreach ($res as $row) {
         if (++$count > $this->limit) {
             // We've had enough
             $this->setContinueEnumParameter('continue', "{$row->rev_timestamp}|{$row->rev_id}");
             break;
         }
         // Miser mode namespace check
         if ($miser_ns !== null && !in_array($row->page_namespace, $miser_ns)) {
             continue;
         }
         if ($resultPageSet !== null) {
             if ($params['generatetitles']) {
                 $generated[$row->rev_page] = $row->rev_page;
             } else {
                 $generated[] = $row->rev_id;
             }
         } else {
             $revision = Revision::newFromRow($row);
             $rev = $this->extractRevisionInfo($revision, $row);
             if (!isset($pageMap[$row->rev_page])) {
                 $index = $nextIndex++;
                 $pageMap[$row->rev_page] = $index;
                 $title = $revision->getTitle();
                 $a = array('pageid' => $title->getArticleID(), 'revisions' => array($rev));
                 ApiResult::setIndexedTagName($a['revisions'], 'rev');
                 ApiQueryBase::addTitleInfo($a, $title);
                 $fit = $result->addValue(array('query', $this->getModuleName()), $index, $a);
             } else {
                 $index = $pageMap[$row->rev_page];
                 $fit = $result->addValue(array('query', $this->getModuleName(), $index, 'revisions'), null, $rev);
             }
             if (!$fit) {
                 $this->setContinueEnumParameter('continue', "{$row->rev_timestamp}|{$row->rev_id}");
                 break;
             }
         }
     }
     if ($resultPageSet !== null) {
         if ($params['generatetitles']) {
             $resultPageSet->populateFromPageIDs($generated);
         } else {
             $resultPageSet->populateFromRevisionIDs($generated);
         }
     } else {
         $result->addIndexedTagName(array('query', $this->getModuleName()), 'page');
     }
 }
 /**
  * @param ApiPageSet $resultPageSet
  * @return void
  */
 private function run($resultPageSet = null)
 {
     $params = $this->extractRequestParams();
     $this->addTables('protected_titles');
     $this->addFields(array('pt_namespace', 'pt_title', 'pt_timestamp'));
     $prop = array_flip($params['prop']);
     $this->addFieldsIf('pt_user', isset($prop['user']) || isset($prop['userid']));
     $this->addFieldsIf('pt_reason', isset($prop['comment']) || isset($prop['parsedcomment']));
     $this->addFieldsIf('pt_expiry', isset($prop['expiry']));
     $this->addFieldsIf('pt_create_perm', isset($prop['level']));
     $this->addTimestampWhereRange('pt_timestamp', $params['dir'], $params['start'], $params['end']);
     $this->addWhereFld('pt_namespace', $params['namespace']);
     $this->addWhereFld('pt_create_perm', $params['level']);
     // Include in ORDER BY for uniqueness
     $this->addWhereRange('pt_namespace', $params['dir'], null, null);
     $this->addWhereRange('pt_title', $params['dir'], null, null);
     if (!is_null($params['continue'])) {
         $cont = explode('|', $params['continue']);
         $this->dieContinueUsageIf(count($cont) != 3);
         $op = $params['dir'] === 'newer' ? '>' : '<';
         $db = $this->getDB();
         $continueTimestamp = $db->addQuotes($db->timestamp($cont[0]));
         $continueNs = (int) $cont[1];
         $this->dieContinueUsageIf($continueNs != $cont[1]);
         $continueTitle = $db->addQuotes($cont[2]);
         $this->addWhere("pt_timestamp {$op} {$continueTimestamp} OR " . "(pt_timestamp = {$continueTimestamp} AND " . "(pt_namespace {$op} {$continueNs} OR " . "(pt_namespace = {$continueNs} AND " . "pt_title {$op}= {$continueTitle})))");
     }
     if (isset($prop['user'])) {
         $this->addTables('user');
         $this->addFields('user_name');
         $this->addJoinConds(array('user' => array('LEFT JOIN', 'user_id=pt_user')));
     }
     $this->addOption('LIMIT', $params['limit'] + 1);
     $res = $this->select(__METHOD__);
     $count = 0;
     $result = $this->getResult();
     $titles = array();
     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->pt_timestamp}|{$row->pt_namespace}|{$row->pt_title}");
             break;
         }
         $title = Title::makeTitle($row->pt_namespace, $row->pt_title);
         if (is_null($resultPageSet)) {
             $vals = array();
             ApiQueryBase::addTitleInfo($vals, $title);
             if (isset($prop['timestamp'])) {
                 $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $row->pt_timestamp);
             }
             if (isset($prop['user']) && !is_null($row->user_name)) {
                 $vals['user'] = $row->user_name;
             }
             if (isset($prop['userid']) || isset($prop['user'])) {
                 $vals['userid'] = (int) $row->pt_user;
             }
             if (isset($prop['comment'])) {
                 $vals['comment'] = $row->pt_reason;
             }
             if (isset($prop['parsedcomment'])) {
                 $vals['parsedcomment'] = Linker::formatComment($row->pt_reason, $title);
             }
             if (isset($prop['expiry'])) {
                 global $wgContLang;
                 $vals['expiry'] = $wgContLang->formatExpiry($row->pt_expiry, TS_ISO_8601);
             }
             if (isset($prop['level'])) {
                 $vals['level'] = $row->pt_create_perm;
             }
             $fit = $result->addValue(array('query', $this->getModuleName()), null, $vals);
             if (!$fit) {
                 $this->setContinueEnumParameter('continue', "{$row->pt_timestamp}|{$row->pt_namespace}|{$row->pt_title}");
                 break;
             }
         } else {
             $titles[] = $title;
         }
     }
     if (is_null($resultPageSet)) {
         $result->addIndexedTagName(array('query', $this->getModuleName()), $this->getModulePrefix());
     } else {
         $resultPageSet->populateFromTitles($titles);
     }
 }
Example #30
0
 /**
  * @param Title $title
  * @param Title $origTitle
  * @param int $revisionCount
  * @param int $successCount
  * @param array $pageInfo
  * @return void
  */
 function reportPage($title, $origTitle, $revisionCount, $successCount, $pageInfo)
 {
     // Add a result entry
     $r = array();
     if ($title === null) {
         # Invalid or non-importable title
         $r['title'] = $pageInfo['title'];
         $r['invalid'] = true;
     } else {
         ApiQueryBase::addTitleInfo($r, $title);
         $r['revisions'] = intval($successCount);
     }
     $this->mResultArr[] = $r;
     // Piggyback on the parent to do the logging
     parent::reportPage($title, $origTitle, $revisionCount, $successCount, $pageInfo);
 }