Example #1
0
 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;
 }
Example #3
0
 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']);
 }
Example #7
0
 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');
     }
 }
Example #9
0
 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);
 }
Example #10
0
 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 );
	}
Example #12
0
 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);
 }
Example #14
0
 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);
 }
Example #16
0
 /**
  * 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));
     }
 }
Example #17
0
 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);
 }
Example #18
0
 /**
  * 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));
     }
 }
Example #19
0
 /**
  * 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;
             }
         }
     }
 }
Example #20
0
 /**
  * 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);
     }
 }
Example #23
0
 /**
  * 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;
 }
Example #24
0
 public function execute()
 {
     ApiBase::dieDebug(__METHOD__, 'execute() is not supported on Result object');
 }
Example #25
0
 /**
  * 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);
 }
Example #26
0
 /**
  * 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));
     }
 }
Example #27
0
 /**
  * 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);
 }
Example #28
0
 /**
  * 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);
     }
 }
Example #30
0
 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');
     }
 }