2006-09-26 05:43:02 +00:00
< ? php
/*
* Created on Sep 7 , 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
2006-10-01 02:02:13 +00:00
require_once ( 'ApiQueryBase.php' );
2006-09-26 05:43:02 +00:00
}
class ApiQueryRevisions extends ApiQueryBase {
2006-10-03 05:41:55 +00:00
public function __construct ( $query , $moduleName ) {
parent :: __construct ( $query , $moduleName , 'rv' );
2006-09-26 05:43:02 +00:00
}
2006-09-27 05:13:48 +00:00
public function execute () {
2006-10-03 05:41:55 +00:00
$limit = $startid = $endid = $start = $end = $dir = $prop = null ;
2006-09-27 05:13:48 +00:00
extract ( $this -> extractRequestParams ());
2006-09-26 05:43:02 +00:00
2006-10-01 02:02:13 +00:00
// If any of those parameters are used, work in 'enumeration' mode.
2006-09-30 08:06:27 +00:00
// Enum mode can only be used when exactly one page is provided.
2006-09-29 07:29:13 +00:00
// Enumerating revisions on multiple pages make it extremelly
// difficult to manage continuations and require additional sql indexes
2006-10-21 08:26:32 +00:00
$enumRevMode = ( ! is_null ( $limit ) || ! is_null ( $startid ) || ! is_null ( $endid ) || $dir === 'newer' || ! is_null ( $start ) || ! is_null ( $end ));
2006-09-27 05:13:48 +00:00
2006-10-01 20:17:16 +00:00
$pageSet = $this -> getPageSet ();
$pageCount = $pageSet -> getGoodTitleCount ();
$revCount = $pageSet -> getRevisionCount ();
2006-09-29 07:29:13 +00:00
2006-10-01 02:02:13 +00:00
// Optimization -- nothing to do
if ( $revCount === 0 && $pageCount === 0 )
return ;
2006-09-30 08:06:27 +00:00
if ( $revCount > 0 && $enumRevMode )
2006-10-03 05:41:55 +00:00
$this -> dieUsage ( 'The revids= parameter may not be used with the list options (limit, startid, endid, dirNewer, start, end).' , 'revids' );
2006-09-30 08:06:27 +00:00
2006-10-13 04:59:14 +00:00
if ( $pageCount > 1 && $enumRevMode )
2006-10-03 05:41:55 +00:00
$this -> dieUsage ( 'titles, pageids or a generator was used to supply multiple pages, but the limit, startid, endid, dirNewer, start, and end parameters may only be used on a single page.' , 'multpages' );
2006-09-27 05:13:48 +00:00
2006-10-21 08:26:32 +00:00
$this -> addTables ( 'revision' );
$this -> addFields ( array (
2006-09-27 05:13:48 +00:00
'rev_id' ,
'rev_page' ,
'rev_text_id' ,
'rev_minor_edit'
2006-10-21 08:26:32 +00:00
));
$this -> addWhere ( 'rev_deleted=0' );
$showContent = false ;
2006-09-27 05:13:48 +00:00
2006-10-16 00:08:03 +00:00
if ( ! is_null ( $prop )) {
2006-10-21 08:26:32 +00:00
$prop = array_flip ( $prop );
$this -> addFieldsIf ( 'rev_timestamp' , isset ( $prop [ 'timestamp' ]));
$this -> addFieldsIf ( 'rev_comment' , isset ( $prop [ 'comment' ]));
if ( isset ( $prop [ 'user' ])) {
$this -> addFields ( 'rev_user' );
$this -> addFields ( 'rev_user_text' );
}
if ( isset ( $prop [ 'content' ])) {
$this -> addTables ( 'text' );
$this -> addWhere ( 'rev_text_id=old_id' );
$this -> addFields ( 'old_id' );
$this -> addFields ( 'old_text' );
$this -> addFields ( 'old_flags' );
$showContent = true ;
2006-09-27 05:13:48 +00:00
}
}
2006-09-29 07:29:13 +00:00
$userMax = ( $showContent ? 50 : 500 );
$botMax = ( $showContent ? 200 : 10000 );
if ( $enumRevMode ) {
2006-09-27 05:13:48 +00:00
2006-09-30 08:06:27 +00:00
// This is mostly to prevent parameter errors (and optimize sql?)
2006-10-16 00:08:03 +00:00
if ( ! is_null ( $startid ) && ! is_null ( $start ))
2006-10-03 05:41:55 +00:00
$this -> dieUsage ( 'start and startid cannot be used together' , 'badparams' );
2006-09-30 08:06:27 +00:00
2006-10-16 00:08:03 +00:00
if ( ! is_null ( $endid ) && ! is_null ( $end ))
2006-10-03 05:41:55 +00:00
$this -> dieUsage ( 'end and endid cannot be used together' , 'badparams' );
2006-09-30 08:06:27 +00:00
2006-10-02 18:27:06 +00:00
// 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.
2006-10-21 08:26:32 +00:00
if ( is_null ( $startid ))
$this -> addWhereRange ( 'rev_id' , $dir , $startid , $endid );
else
$this -> addWhereRange ( 'rev_timestamp' , $dir , $start , $end );
2006-09-29 07:29:13 +00:00
2006-10-03 05:41:55 +00:00
// must manually initialize unset limit
2006-10-18 23:49:09 +00:00
if ( is_null ( $limit ))
2006-10-03 05:41:55 +00:00
$limit = 10 ;
$this -> validateLimit ( $this -> encodeParamName ( 'limit' ), $limit , 1 , $userMax , $botMax );
2006-09-29 07:29:13 +00:00
2006-09-30 08:06:27 +00:00
// There is only one ID, use it
2006-10-21 08:26:32 +00:00
$this -> addWhereFld ( 'rev_page' , array_pop ( array_keys ( $pageSet -> getGoodTitles ())));
2006-10-01 20:17:16 +00:00
}
elseif ( $pageCount > 0 ) {
// When working in multi-page non-enumeration mode,
// limit to the latest revision only
2006-10-21 08:26:32 +00:00
$this -> addTables ( 'page' );
$this -> addWhere ( 'page_id=rev_page' );
$this -> addWhere ( 'page_latest=rev_id' );
2006-10-01 20:17:16 +00:00
$this -> validateLimit ( 'page_count' , $pageCount , 1 , $userMax , $botMax );
// Get all page IDs
2006-10-21 08:26:32 +00:00
$this -> addWhereFld ( 'page_id' , array_keys ( $pageSet -> getGoodTitles ()));
2006-10-01 20:17:16 +00:00
2006-10-03 05:41:55 +00:00
$limit = $pageCount ; // assumption testing -- we should never get more then $pageCount rows.
2006-10-01 20:17:16 +00:00
}
elseif ( $revCount > 0 ) {
$this -> validateLimit ( 'rev_count' , $revCount , 1 , $userMax , $botMax );
2006-09-30 08:06:27 +00:00
2006-10-01 20:17:16 +00:00
// Get all revision IDs
2006-10-21 08:26:32 +00:00
$this -> addWhereFld ( 'rev_id' , array_keys ( $pageSet -> getRevisionIDs ()));
2006-09-27 05:13:48 +00:00
2006-10-03 05:41:55 +00:00
$limit = $revCount ; // assumption testing -- we should never get more then $revCount rows.
2006-10-01 20:17:16 +00:00
} else
ApiBase :: dieDebug ( __METHOD__ , 'param validation?' );
2006-09-30 08:06:27 +00:00
2006-10-21 08:26:32 +00:00
$this -> addOption ( 'LIMIT' , $limit + 1 );
2006-09-27 05:13:48 +00:00
$data = array ();
$count = 0 ;
2006-10-21 08:26:32 +00:00
$db = $this -> getDB ();
$res = $this -> select ( __METHOD__ );
2006-09-27 05:13:48 +00:00
while ( $row = $db -> fetchObject ( $res )) {
2006-10-03 05:41:55 +00:00
if ( ++ $count > $limit ) {
2006-09-27 05:13:48 +00:00
// We've reached the one extra which shows that there are additional pages to be had. Stop here...
2006-09-30 08:06:27 +00:00
if ( ! $enumRevMode )
2006-10-01 20:17:16 +00:00
ApiBase :: dieDebug ( __METHOD__ , 'Got more rows then expected' ); // bug report
2006-10-16 00:08:03 +00:00
$this -> setContinueEnumParameter ( 'startid' , $row -> rev_id );
2006-09-27 05:13:48 +00:00
break ;
}
2006-10-21 08:26:32 +00:00
$vals = $this -> addRowInfo ( 'rev' , $row );
if ( $vals ) {
if ( $showContent )
ApiResult :: setContent ( $vals , Revision :: getRevisionText ( $row ));
2006-09-29 07:29:13 +00:00
2006-10-21 08:26:32 +00:00
$this -> getResult () -> addValue ( array (
'query' ,
'pages' ,
intval ( $row -> rev_page
), 'revisions' ), intval ( $row -> rev_id ), $vals );
2006-09-27 05:13:48 +00:00
}
}
$db -> freeResult ( $res );
2006-10-18 05:35:24 +00:00
// Ensure that all revisions are shown as '<rev>' elements
2006-10-18 05:27:43 +00:00
$result = $this -> getResult ();
2006-10-21 08:26:32 +00:00
if ( $result -> getIsRawMode ()) {
2006-10-18 05:35:24 +00:00
$data = & $result -> getData ();
foreach ( $data [ 'query' ][ 'pages' ] as & $page ) {
if ( is_array ( $page ) && array_key_exists ( 'revisions' , $page )) {
$result -> setIndexedTagName ( $page [ 'revisions' ], 'rev' );
}
2006-10-01 02:02:13 +00:00
}
}
2006-09-26 05:43:02 +00:00
}
2006-09-27 05:13:48 +00:00
protected function getAllowedParams () {
2006-09-26 05:43:02 +00:00
return array (
2006-10-03 05:41:55 +00:00
'prop' => array (
2006-10-01 20:17:16 +00:00
ApiBase :: PARAM_ISMULTI => true ,
ApiBase :: PARAM_TYPE => array (
'timestamp' ,
'user' ,
'comment' ,
'content'
)
),
2006-10-03 05:41:55 +00:00
'limit' => array (
2006-10-01 20:17:16 +00:00
ApiBase :: PARAM_TYPE => 'limit' ,
2006-10-17 02:01:20 +00:00
ApiBase :: PARAM_MIN => 1 ,
ApiBase :: PARAM_MAX1 => ApiBase :: LIMIT_SML1 ,
ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_SML2
2006-09-27 05:13:48 +00:00
),
2006-10-16 00:08:03 +00:00
'startid' => array (
ApiBase :: PARAM_TYPE => 'integer'
),
'endid' => array (
ApiBase :: PARAM_TYPE => 'integer'
),
2006-10-03 05:41:55 +00:00
'start' => array (
2006-10-01 20:17:16 +00:00
ApiBase :: PARAM_TYPE => 'timestamp'
2006-09-26 05:43:02 +00:00
),
2006-10-03 05:41:55 +00:00
'end' => array (
2006-10-01 20:17:16 +00:00
ApiBase :: PARAM_TYPE => 'timestamp'
2006-09-26 05:43:02 +00:00
),
2006-10-03 05:41:55 +00:00
'dir' => array (
2006-10-01 20:17:16 +00:00
ApiBase :: PARAM_DFLT => 'older' ,
ApiBase :: PARAM_TYPE => array (
2006-09-26 05:43:02 +00:00
'newer' ,
'older'
)
)
);
}
2006-10-01 20:17:16 +00:00
protected function getParamDescription () {
return array (
2006-10-16 00:08:03 +00:00
'prop' => 'Which properties to get for each revision.' ,
2006-10-03 05:41:55 +00:00
'limit' => 'limit how many revisions will be returned (enum)' ,
'startid' => 'from which revision id to start enumeration (enum)' ,
'endid' => 'stop revision enumeration on this revid (enum)' ,
'start' => 'from which revision timestamp to start enumeration (enum)' ,
'end' => 'enumerate up to this timestamp (enum)' ,
'dir' => 'direction of enumeration - towards "newer" or "older" revisions (enum)'
2006-10-01 20:17:16 +00:00
);
}
2006-09-27 05:13:48 +00:00
protected function getDescription () {
2006-09-30 08:06:27 +00:00
return array (
'Get revision information.' ,
'This module may be used in several ways:' ,
' 1) Get data about a set of pages (last revision), by setting titles or pageids parameter.' ,
2006-10-03 05:41:55 +00:00
' 2) Get revisions for one given page, by using titles/pageids with start/end/limit params.' ,
2006-10-01 20:17:16 +00:00
' 3) Get data about a set of revisions by setting their IDs with revids parameter.' ,
'All parameters marked as (enum) may only be used with a single page (#2).'
2006-09-30 08:06:27 +00:00
);
2006-09-26 05:43:02 +00:00
}
2006-09-27 05:13:48 +00:00
protected function getExamples () {
2006-09-26 05:43:02 +00:00
return array (
2006-10-01 20:17:16 +00:00
'Get data with content for the last revision of titles "API" and "Main Page":' ,
' api.php?action=query&prop=revisions&titles=API|Main%20Page&rvprop=timestamp|user|comment|content' ,
'Get last 5 revisions of the "Main Page":' ,
' api.php?action=query&prop=revisions&titles=Main%20Page&rvlimit=5&rvprop=timestamp|user|comment' ,
'Get first 5 revisions of the "Main Page":' ,
' api.php?action=query&prop=revisions&titles=Main%20Page&rvlimit=5&rvprop=timestamp|user|comment&rvdir=newer' ,
'Get first 5 revisions of the "Main Page" made after 2006-05-01:' ,
' api.php?action=query&prop=revisions&titles=Main%20Page&rvlimit=5&rvprop=timestamp|user|comment&rvdir=newer&rvstart=20060501000000'
2006-09-26 05:43:02 +00:00
);
}
2006-10-01 21:20:55 +00:00
public function getVersion () {
return __CLASS__ . ': $Id$' ;
}
2006-09-26 05:43:02 +00:00
}
2006-10-21 08:26:32 +00:00
?>