'ApiQueryBase' => 'includes/api/ApiQueryBase.php',
'ApiQueryInfo' => 'includes/api/ApiQueryInfo.php',
'ApiQueryLogEvents' => 'includes/api/ApiQueryLogEvents.php',
+ 'ApiQueryRecentChanges'=> 'includes/api/ApiQueryRecentChanges.php',
'ApiQueryRevisions' => 'includes/api/ApiQueryRevisions.php',
'ApiQuerySiteinfo' => 'includes/api/ApiQuerySiteinfo.php',
'ApiQueryWatchlist' => 'includes/api/ApiQueryWatchlist.php',
$module = new ApiMain($params);
$module->execute();
- // Get clean data
+ // Get resulting data
$data = & $module->getResultData();
// Reformat useful data for future printing by JSON engine
private $mQueryListModules = array (
'allpages' => 'ApiQueryAllpages',
'logevents' => 'ApiQueryLogEvents',
- 'watchlist' => 'ApiQueryWatchlist'
+ 'watchlist' => 'ApiQueryWatchlist',
+ 'recentchanges' => 'ApiQueryRecentChanges'
);
// 'backlinks' => 'ApiQueryBacklinks',
// 'categorymembers' => 'ApiQueryCategorymembers',
$db = $this->getDB();
- $where = array (
- 'page_namespace' => $namespace
- );
-
- if (isset ($from)) {
- $where[] = 'page_title>=' . $db->addQuotes(ApiQueryBase :: titleToKey($from));
- }
-
- if (isset ($prefix)) {
- $where[] = "page_title LIKE '{$db->strencode(ApiQueryBase :: titleToKey($prefix))}%'";
- }
-
- if ($filterredir === 'redirects') {
- $where['page_is_redirect'] = 1;
- }
- elseif ($filterredir === 'nonredirects') {
- $where['page_is_redirect'] = 0;
- }
+ $this->addTables('page');
+ $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)) {
- $fields = array (
+ $this->addFields( array (
'page_id',
'page_namespace',
'page_title'
- );
+ ));
} else {
- $fields = $resultPageSet->getPageTableFields();
+ $this->addFields( $resultPageSet->getPageTableFields());
}
- $options = array (
- 'USE INDEX' => 'name_title',
- 'LIMIT' => $limit +1,
- 'ORDER BY' => 'page_namespace, page_title'
- );
-
- $this->profileDBIn();
- $res = $db->select('page', $fields, $where, __METHOD__, $options);
- $this->profileDBOut();
+ $this->addOption( 'USE INDEX', 'name_title');
+ $this->addOption( 'LIMIT', $limit +1);
+ $this->addOption( 'ORDER BY', 'page_namespace, page_title');
$data = array ();
$count = 0;
+ $res = $this->select(__METHOD__);
while ($row = $db->fetchObject($res)) {
if (++ $count > $limit) {
// We've reached the one extra which shows that there are additional pages to be had. Stop here...
abstract class ApiQueryBase extends ApiBase {
- private $mQueryModule;
+ private $mQueryModule, $tables, $where, $fields, $options;
public function __construct($query, $moduleName, $paramPrefix = '') {
parent :: __construct($query->getMain(), $moduleName, $paramPrefix);
$this->mQueryModule = $query;
+
+ $this->tables = array ();
+ $this->where = array ();
+ $this->fields = array();
+ $this->options = array ();
+ }
+
+ protected function addTables($value) {
+ if(!is_array($this->tables))
+ $this->dieDebug(__METHOD__, 'Must not call setTablesAsExpression() before this method');
+ if(is_array($value))
+ $this->tables = array_merge($this->tables, $value);
+ else
+ $this->tables[] = $value;
+ }
+
+ protected function setTablesAsExpression($value) {
+ if(!empty($this->tables))
+ $this->dieDebug(__METHOD__, 'Must not call addTables() before this method');
+ $this->tables = $value;
}
+ protected function addFields($value) {
+ if(is_array($value))
+ $this->fields = array_merge($this->fields, $value);
+ else
+ $this->fields[] = $value;
+ }
+
+ protected function addFieldsIf($value, $condition) {
+ if ($condition)
+ $this->addFields($value);
+ }
+
+ protected function addWhere($value) {
+ if(is_array($value))
+ $this->where = array_merge($this->where, $value);
+ else
+ $this->where[] = $value;
+ }
+
+ protected function addWhereIf($value, $condition) {
+ if ($condition)
+ $this->addWhere($value);
+ }
+
+ protected function addWhereFld($field, $value) {
+ if(!is_null($value))
+ $this->where[$field] = $value;
+ }
+
+ protected function addWhereRange($field, $dir, $start, $end) {
+ $isDirNewer = ($dir === 'newer');
+ $after = ($isDirNewer ? '<=' : '>=');
+ $before = ($isDirNewer ? '>=' : '<=');
+ $db = $this->getDB();
+
+ if (!is_null($start))
+ $this->addWhere($field . $after . $db->addQuotes($start));
+
+ if (!is_null($end))
+ $this->addWhere($field . $before . $db->addQuotes($end));
+
+ $this->addOption('ORDER BY', $field . ($isDirNewer ? '' : ' DESC'));
+ }
+
+ protected function select($method) {
+ $this->profileDBIn();
+ $res = $this->getDB()->select($this->tables, $this->fields, $this->where, $method, $this->options);
+ $this->profileDBOut();
+ return $res;
+ }
+
+ protected function addOption($name, $value) {
+ $this->options[$name] = $value;
+ }
+
/**
* Override this method to request extra fields from the pageSet
* using $this->getPageSet()->requestField('fieldName')
$pageLatest = $pageSet->getCustomField('page_latest');
foreach ($titles as $pageid => $title) {
- $pageInfo = array ('touched' => $pageTouched[$pageid], 'lastrevid' => $pageLatest[$pageid]);
+ $pageInfo = array (
+ 'touched' => $pageTouched[$pageid],
+ 'lastrevid' => $pageLatest[$pageid]
+ );
if ($pageIsRedir[$pageid])
$pageInfo['redirect'] = '';
$db = $this->getDB();
extract($db->tableNames('logging', 'page', 'user'), EXTR_PREFIX_ALL, 'tbl');
- $tables = "$tbl_logging LEFT OUTER JOIN $tbl_page ON " .
+ $this->setTablesAsExpression("$tbl_logging LEFT OUTER JOIN $tbl_page ON " .
"log_namespace=page_namespace AND log_title=page_title " .
- "INNER JOIN $tbl_user ON user_id=log_user";
+ "INNER JOIN $tbl_user ON user_id=log_user");
- $fields = array (
+ $this->addFields(array (
'log_type',
'log_action',
'log_timestamp',
'page_id',
'log_comment',
'log_params'
- );
+ ));
- $where = array ();
- if (!is_null($type))
- $where['log_type'] = $type;
+ $this->addWhereFld('log_type', $type);
+ $this->addWhereRange('log_timestamp', $dir, $start, $end);
+ $this->addOption('LIMIT', $limit +1);
if (!is_null($user)) {
$userid = $db->selectField('user', 'user_id', array (
));
if (!$userid)
$this->dieUsage("User name $user not found", 'param_user');
- $where['log_user'] = $userid;
+ $this->addWhereFld('log_user', $userid);
}
if (!is_null($title)) {
$titleObj = Title :: newFromText($title);
if (is_null($titleObj))
$this->dieUsage("Bad title value '$title'", 'param_title');
- $where['log_namespace'] = $titleObj->getNamespace();
- $where['log_title'] = $titleObj->getDBkey();
+ $this->addWhereFld('log_namespace', $titleObj->getNamespace());
+ $this->addWhereFld('log_title', $titleObj->getDBkey());
}
- $dirNewer = ($dir === 'newer');
- $before = ($dirNewer ? '<=' : '>=');
- $after = ($dirNewer ? '>=' : '<=');
-
- if (!is_null($start))
- $where[] = 'log_timestamp' . $after . $db->addQuotes($start);
- if (!is_null($end))
- $where[] = 'log_timestamp' . $before . $db->addQuotes($end);
-
- $options = array (
- 'LIMIT' => $limit +1,
- 'ORDER BY' => 'log_timestamp' . ($dirNewer ? '' : ' DESC'
- ));
-
- $this->profileDBIn();
- $res = $db->select($tables, $fields, $where, __METHOD__, $options);
- $this->profileDBOut();
-
$data = array ();
$count = 0;
+ $res = $this->select(__METHOD__);
while ($row = $db->fetchObject($res)) {
if (++ $count > $limit) {
// We've reached the one extra which shows that there are additional pages to be had. Stop here...
$params = null;
}
}
-
- if(!empty($params)) {
+
+ if (!empty ($params)) {
$this->getResult()->setIndexedTagName($params, 'param');
$vals = array_merge($vals, $params);
}
--- /dev/null
+<?php
+
+
+/*
+ * Created on Oct 19, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+ // Eclipse helper - will be ignored in production
+ require_once ('ApiQueryBase.php');
+}
+
+class ApiQueryRecentChanges extends ApiQueryBase {
+
+ public function __construct($query, $moduleName) {
+ parent :: __construct($query, $moduleName, 'rc');
+ }
+
+ public function execute() {
+ $limit = $from = $namespace = $hide = $dir = $start = $end = null;
+ extract($this->extractRequestParams());
+
+ $this->addTables('recentchanges');
+ $this->addWhereRange('rc_timestamp', $dir, $start, $end);
+ $this->addWhereFld('rc_namespace', $namespace);
+
+ if (!is_null($hide)) {
+ $hide = array_flip($hide);
+ $this->addWhereIf('rc_minor = 0', isset ($hide['minor']));
+ $this->addWhereIf('rc_bot = 0', isset ($hide['bots']));
+ $this->addWhereIf('rc_user != 0', isset ($hide['anons']));
+ $this->addWhereIf('rc_user = 0', isset ($hide['liu']));
+ }
+
+ $this->addFields(array (
+ 'rc_timestamp',
+ 'rc_user',
+ 'rc_user_text',
+ 'rc_namespace',
+ 'rc_title',
+ 'rc_comment',
+ 'rc_minor',
+ 'rc_bot',
+ 'rc_new',
+ 'rc_cur_id',
+ 'rc_this_oldid',
+ 'rc_last_oldid',
+ 'rc_type',
+ 'rc_moved_to_ns',
+ 'rc_moved_to_title'
+ ));
+
+ $this->addOption('LIMIT', $limit +1);
+
+ $data = array ();
+ $count = 0;
+ $db = $this->getDB();
+ $res = $this->select(__METHOD__);
+ while ($row = $db->fetchObject($res)) {
+ if (++ $count > $limit) {
+ // We've reached the one extra which shows that there are additional pages to be had. Stop here...
+ $this->setContinueEnumParameter('start', $row->rc_timestamp);
+ break;
+ }
+
+ $title = Title :: makeTitle($row->rc_namespace, $row->rc_title);
+ // skip any pages that user has no rights to read
+ if ($title->userCanRead()) {
+
+ $id = intval($row->rc_cur_id);
+ $data[] = array (
+ 'id' => $id,
+ 'ns' => $title->getNamespace(), 'title' => $title->getPrefixedText(),
+ 'timestamp' => $row->rc_timestamp,
+ 'user' => $row->rc_user_text,
+ 'comment' => $row->rc_comment,
+ 'this_oldid' => $row->rc_this_oldid,
+ 'last_oldid' => $row->rc_last_oldid,
+ 'type' => $row->rc_type,
+ 'moved_to_ns' => $row->rc_moved_to_ns,
+ 'moved_to_title' => $row->rc_moved_to_title);
+
+ if (!$row->rc_user)
+ $vals['anon'] = '';
+ if ($row->rc_new)
+ $vals['new'] = '';
+ if ($row->rc_bot)
+ $vals['bot'] = '';
+ if ($row->rc_minor)
+ $vals['minor'] = '';
+ }
+ }
+ $db->freeResult($res);
+
+ $result = $this->getResult();
+ $result->setIndexedTagName($data, 'rc');
+ $result->addValue('query', $this->getModuleName(), $data);
+ }
+
+ protected function getAllowedParams() {
+ $namespaces = $this->getQuery()->getValidNamespaces();
+ return array (
+ 'dir' => array (
+ ApiBase :: PARAM_DFLT => 'older',
+ ApiBase :: PARAM_TYPE => array (
+ 'newer',
+ 'older'
+ )
+ ),
+ 'start' => array (
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'end' => array (
+ ApiBase :: PARAM_TYPE => 'timestamp'
+ ),
+ 'namespace' => array (
+ ApiBase :: PARAM_DFLT => 0,
+ ApiBase :: PARAM_TYPE => $namespaces
+ ),
+ 'hide' => array (
+ ApiBase :: PARAM_ISMULTI => true,
+ ApiBase :: PARAM_TYPE => array (
+ 'minor',
+ 'bots',
+ 'anons',
+ 'liu'
+ )
+ ),
+ 'limit' => array (
+ ApiBase :: PARAM_DFLT => 10,
+ ApiBase :: PARAM_TYPE => 'limit',
+ ApiBase :: PARAM_MIN => 1,
+ ApiBase :: PARAM_MAX1 => ApiBase :: LIMIT_BIG1,
+ ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+ )
+ );
+ }
+
+ protected function getParamDescription() {
+ return array (
+ 'start' => 'The timestamp to start enumerating from.',
+ 'end' => 'The timestamp to end enumerating.',
+ 'limit' => 'How many total pages to return.'
+ );
+ }
+
+ protected function getDescription() {
+ return 'Enumerate recent changes';
+ }
+
+ protected function getExamples() {
+ return array (
+ 'api.php?action=query&list=recentchanges',
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id$';
+ }
+}
+?>
\ No newline at end of file
$allrev = $start = $end = $namespace = $dir = $limit = $prop = null;
extract($this->extractRequestParams());
- $db = $this->getDB();
-
- $dirNewer = ($dir === 'newer');
- $after = ($dirNewer ? '<=' : '>=');
- $before = ($dirNewer ? '>=' : '<=');
-
- $tables = array (
- 'watchlist',
- 'page',
- 'recentchanges'
- );
-
- $options = array (
- 'LIMIT' => $limit +1,
- 'ORDER BY' => 'rc_timestamp' . ($dirNewer ? '' : ' DESC'
- ));
-
$patrol = $timestamp = $user = $comment = false;
if (!is_null($prop)) {
if (!is_null($resultPageSet))
}
if (is_null($resultPageSet)) {
- $fields = array (
+ $this->addFields(array (
'rc_cur_id AS page_id',
'rc_this_oldid AS rev_id',
'rc_namespace AS page_namespace',
'rc_title AS page_title',
'rc_new AS page_is_new',
- 'rc_minor AS rev_minor_edit'
- );
- if ($user) {
- $fields[] = 'rc_user AS rev_user';
- $fields[] = 'rc_user_text AS rev_user_text';
- }
- if ($comment)
- $fields[] = 'rc_comment AS rev_comment';
- if ($timestamp)
- $fields[] = 'rc_timestamp AS rev_timestamp';
- if ($patrol)
- $fields[] = 'rc_patrolled';
+ 'rc_minor AS rev_minor_edit',
+ 'rc_timestamp AS rev_timestamp'
+ ));
+
+ $this->addFieldsIf('rc_user AS rev_user', $user);
+ $this->addFieldsIf('rc_user_text AS rev_user_text', $user);
+ $this->addFieldsIf('rc_comment AS rev_comment', $comment);
+ $this->addFieldsIf('rc_patrolled', $patrol);
}
elseif ($allrev) {
- $fields = array (
+ $this->addFields(array (
'rc_this_oldid AS rev_id',
'rc_namespace AS page_namespace',
'rc_title AS page_title',
'rc_timestamp AS rev_timestamp'
- );
+ ));
} else {
- $fields = array (
+ $this->addFields(array (
'rc_cur_id AS page_id',
'rc_namespace AS page_namespace',
'rc_title AS page_title',
'rc_timestamp AS rev_timestamp'
- );
+ ));
}
- $where = array (
+ $this->addTables(array (
+ 'watchlist',
+ 'page',
+ 'recentchanges'
+ ));
+
+ $userId = $wgUser->getID();
+ $this->addWhere(array (
'wl_namespace = rc_namespace',
'wl_title = rc_title',
'rc_cur_id = page_id',
- 'wl_user' => $wgUser->getID());
-
- if (!$allrev)
- $where[] = 'rc_this_oldid=page_latest';
- if (isset ($namespace))
- $where['wl_namespace'] = $namespace;
-
- if (isset ($start))
- $where[] = 'rc_timestamp' . $after . $db->addQuotes($start);
-
- if (isset ($end))
- $where[] = 'rc_timestamp' . $before . $db->addQuotes($end);
-
- if (!isset ($start) && !isset ($end))
- $where[] = "rc_timestamp > ''";
-
- $this->profileDBIn();
- $res = $db->select($tables, $fields, $where, __METHOD__, $options);
- $this->profileDBOut();
+ 'wl_user' => $userId
+ ));
+ $this->addWhereRange('rc_timestamp', $dir, $start, $end);
+ $this->addWhereFld('wl_namespace', $namespace);
+ $this->addWhereIf('rc_this_oldid=page_latest', !$allrev);
+ $this->addWhereIf("rc_timestamp > ''", !isset ($start) && !isset ($end));
+
+ $this->addOption('LIMIT', $limit +1);
$data = array ();
$count = 0;
+ $res = $this->select(__METHOD__);
+
+ $db = $this->getDB();
while ($row = $db->fetchObject($res)) {
if (++ $count > $limit) {
// We've reached the one extra which shows that there are additional pages to be had. Stop here...