86 if ( $this->page === false ) {
87 $this->page = $this->pageLookup->getExistingPageByText(
105 if ( $params[
'older_than'] !==
null && $params[
'newer_than'] !==
null ) {
107 new MessageValue(
'rest-pagehistory-incompatible-params' ), 400 );
110 if ( ( $params[
'older_than'] !==
null && $params[
'older_than'] < 1 ) ||
111 ( $params[
'newer_than'] !==
null && $params[
'newer_than'] < 1 )
114 new MessageValue(
'rest-pagehistory-param-range-error' ), 400 );
118 if ( $params[
'filter'] ===
'reverted' ) {
121 $tagIds[] = $this->changeTagDefStore->getId( $tagName );
128 $page = $this->getPage();
137 if ( !$this->
getAuthority()->authorizeRead(
'read', $page ) ) {
145 $relativeRevId = $params[
'older_than'] ?? $params[
'newer_than'] ?? 0;
146 if ( $relativeRevId ) {
148 $rev = $this->revisionStore->getRevisionByPageId(
160 $ts = $rev->getTimestamp();
161 if ( $ts ===
null ) {
173 $res = $this->getDbResults( $page, $params, $relativeRevId, $ts, $tagIds );
174 $response = $this->processDbResults(
$res, $page, $params );
188 $revQuery = $this->revisionStore->getQueryInfo();
190 'rev_page' => $page->
getId()
193 if ( $params[
'filter'] ) {
196 if ( isset(
$revQuery[
'tables'][
'temp_rev_user'] ) ) {
198 "temp_rev_user.revactor_rev = rev_id AND revactor_page = rev_page";
202 switch ( $params[
'filter'] ) {
204 $cond[] =
'EXISTS(' .
$dbr->selectSQLText(
208 'actor_rev_user.actor_user = ug_user',
209 'ug_group' => $this->groupPermissionsLookup->getGroupsWithPermission(
'bot' ),
210 'ug_expiry IS NULL OR ug_expiry >= ' .
$dbr->addQuotes(
$dbr->timestamp() )
214 $bitmask = $this->getBitmask();
216 $cond[] =
$dbr->bitAnd(
'rev_deleted', $bitmask ) .
" != $bitmask";
221 $cond[] =
"actor_user IS NULL";
222 $bitmask = $this->getBitmask();
224 $cond[] =
$dbr->bitAnd(
'rev_deleted', $bitmask ) .
" != $bitmask";
232 $cond[] =
'EXISTS(' .
$dbr->selectSQLText(
235 [
'ct_rev_id = rev_id',
'ct_tag_id' => $tagIds ],
241 $cond[] =
'rev_minor_edit != 0';
246 if ( $relativeRevId ) {
247 $op = $params[
'older_than'] ?
'<' :
'>';
248 $sort = $params[
'older_than'] ?
'DESC' :
'ASC';
249 $ts =
$dbr->addQuotes(
$dbr->timestamp( $ts ) );
250 $cond[] =
"rev_timestamp $op $ts OR " .
251 "(rev_timestamp = $ts AND rev_id $op $relativeRevId)";
252 $orderBy =
"rev_timestamp $sort, rev_id $sort";
254 $orderBy =
"rev_timestamp DESC, rev_id DESC";
258 $limit = self::REVISIONS_RETURN_LIMIT + 1;
267 'ORDER BY' => $orderBy,
284 if ( !$this->
getAuthority()->isAllowed(
'deletedhistory' ) ) {
286 } elseif ( !$this->
getAuthority()->isAllowedAny(
'suppressrevision',
'viewsuppressed' ) ) {
305 foreach (
$res as $row ) {
306 $rev = $this->revisionStore->newRevisionFromRow(
308 IDBAccessObject::READ_NORMAL,
312 $firstRevId = $row->rev_id;
314 $lastRevId = $row->rev_id;
317 'id' => $rev->getId(),
318 'timestamp' =>
wfTimestamp( TS_ISO_8601, $rev->getTimestamp() ),
319 'minor' => $rev->isMinor(),
320 'size' => $rev->getSize()
325 $sizes[$rev->getId()] = $rev->getSize();
326 $parentId = $rev->getParentId();
328 $revision[
'parent_id'] = $parentId;
332 $revision[
'comment'] = $comment ? $comment->text :
null;
336 $revision[
'user'] = [
337 'id' => $revUser->isRegistered() ? $revUser->getId() :
null,
338 'name' => $revUser->getName()
341 $revision[
'user'] =
null;
344 $revisions[] = $revision;
347 if ( count( $revisions ) == self::REVISIONS_RETURN_LIMIT ) {
354 foreach ( $revisions as $revision ) {
355 if ( isset( $revision[
'parent_id'] ) && !isset( $sizes[$revision[
'parent_id']] ) ) {
356 $unknownSizes[] = $revision[
'parent_id'];
359 if ( $unknownSizes ) {
360 $sizes += $this->revisionStore->getRevisionSizes( $unknownSizes );
362 foreach ( $revisions as &$revision ) {
363 $revision[
'delta'] =
null;
364 if ( isset( $revision[
'parent_id'] ) ) {
365 if ( isset( $sizes[$revision[
'parent_id']] ) ) {
366 $revision[
'delta'] = $revision[
'size'] - $sizes[$revision[
'parent_id']];
370 unset( $revision[
'parent_id'] );
374 if ( $revisions && $params[
'newer_than'] ) {
375 $revisions = array_reverse( $revisions );
381 $lastRevId = $firstRevId;
387 'revisions' => $revisions
393 if ( $params[
'newer_than'] ||
$res->numRows() > self::REVISIONS_RETURN_LIMIT ) {
398 if ( $params[
'older_than'] ||
399 ( $params[
'newer_than'] &&
$res->numRows() > self::REVISIONS_RETURN_LIMIT )
403 $newer = $firstRevId;
409 if ( isset( $params[
'filter'] ) ) {
410 $queryParts[
'filter'] = $params[
'filter'];
413 $pathParams = [
'title' => $this->titleFormatter->getPrefixedDBkey( $page ) ];
415 $response[
'latest'] = $this->
getRouteUrl( $pathParams, $queryParts );
417 if ( isset( $older ) ) {
419 $this->
getRouteUrl( $pathParams, $queryParts + [
'older_than' => $older ] );
421 if ( isset( $newer ) ) {
423 $this->
getRouteUrl( $pathParams, $queryParts + [
'newer_than' => $newer ] );
436 self::PARAM_SOURCE =>
'path',
441 self::PARAM_SOURCE =>
'query',
446 self::PARAM_SOURCE =>
'query',
451 self::PARAM_SOURCE =>
'query',
464 $page = $this->getPage();
469 return '"' . $page->getLatest() .
'"';
478 $page = $this->getPage();
483 $rev = $this->revisionStore->getKnownCurrentRevision( $page );
484 return $rev->getTimestamp();
491 return (
bool)$this->getPage();
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
if(!defined('MW_SETUP_CALLBACK'))
The persistent session ID (if any) loaded at startup.
Handler class for Core REST API endpoints that perform operations on revisions.
getETag()
Returns an ETag representing a page's latest revision.
RevisionStore $revisionStore
const ALLOWED_FILTER_TYPES
ILoadBalancer $loadBalancer
getLastModified()
Returns the time of the last change to the page.
NameTableStore $changeTagDefStore
processDbResults( $res, $page, $params)
getBitmask()
Helper function for rev_deleted/user rights query conditions.
needsWriteAccess()
Indicates whether this route requires write access.
run( $title)
At most one of older_than and newer_than may be specified.
TitleFormatter $titleFormatter
getDbResults(ExistingPageRecord $page, array $params, $relativeRevId, $ts, $tagIds)
getParamSettings()
Fetch ParamValidator settings for parameters.
__construct(RevisionStore $revisionStore, NameTableStoreFactory $nameTableStoreFactory, GroupPermissionsLookup $groupPermissionsLookup, ILoadBalancer $loadBalancer, PageLookup $pageLookup, TitleFormatter $titleFormatter)
RevisionStore $revisionStore.
const REVISIONS_RETURN_LIMIT
ExistingPageRecord false null $page
GroupPermissionsLookup $groupPermissionsLookup
Interface for database access objects.
Service for looking up information about wiki pages.
getId( $wikiId=self::LOCAL)
Returns the page ID.