58 return $this->
msg(
'history-title', $this->
getTitle()->getPrefixedText() )->text();
63 $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
64 $subtitle = $linkRenderer->makeKnownLink(
66 $this->
msg(
'viewpagelogs' )->text(),
68 [
'page' => $this->
getTitle()->getPrefixedText() ]
76 . $this->
msg(
'word-separator' )->escaped()
77 . $this->
msg(
'parentheses' )
78 ->rawParams( $this->
getLanguage()->pipeList( $links ) )
81 return Html::rawElement(
'div', [
'class' =>
'mw-history-subtitle' ], $subtitle );
97 if ( !isset( $this->message ) ) {
99 $msgs = [
'cur',
'last',
'pipe-separator' ];
100 foreach ( $msgs as $msg ) {
101 $this->message[$msg] = $this->
msg( $msg )->escaped();
112 $year = $request->
getInt(
'year' );
113 $month = $request->
getInt(
'month' );
115 if ( $year !== 0 || $month !== 0 ) {
119 if ( $month < 1 || $month > 12 ) {
124 $day = cal_days_in_month( CAL_GREGORIAN, $month, $year );
127 $month = str_pad( $month, 2,
"0", STR_PAD_LEFT );
128 $day = str_pad( $day, 2,
"0", STR_PAD_LEFT );
131 $before = $request->
getVal(
'date-range-to' );
133 $parts = explode(
'-', $before );
136 if ( count( $parts ) === 3 ) {
141 return $year && $month && $day ? $year .
'-' . $month .
'-' . $day :
'';
161 $out->checkLastModified( $this->page->getTouched() )
167 $config = $this->context->getConfig();
169 # Fill in the file cache if not set already
172 if ( !
$cache->isCacheGood( ) ) {
173 ob_start( [ &
$cache,
'saveToFileCache' ] );
178 $out->setFeedAppendQuery(
'action=history' );
179 $out->addModules(
'mediawiki.action.history' );
180 $out->addModuleStyles( [
181 'mediawiki.interface.helpers.styles',
182 'mediawiki.action.history.styles',
183 'mediawiki.special.changeslist',
185 if ( $config->get(
'UseMediaWikiUIEverywhere' ) ) {
187 $out->addModuleStyles( [
188 'mediawiki.ui.input',
189 'mediawiki.ui.checkbox',
194 $feedType = $request->getRawVal(
'feed' );
195 if ( $feedType !==
null ) {
196 $this->
feed( $feedType );
201 'https://meta.wikimedia.org/wiki/Special:MyLanguage/Help:Page_history',
206 if ( !$this->page->exists() ) {
209 $out->setStatusCode( 404 );
211 $out->addWikiMsg(
'nohistory' );
215 # show deletion/move log if there is an entry
218 [
'delete',
'move',
'protect' ],
222 'conds' => [
'log_action != ' .
$dbr->addQuotes(
'revision' ) ],
223 'showIfEmpty' =>
false,
224 'msgKey' => [
'moveddeleted-notice' ]
232 $tagFilter = $request->getVal(
'tagfilter' );
237 if ( $request->getBool(
'deleted' ) ) {
238 $conds = [
'rev_deleted != 0' ];
248 'default' => $this->
getTitle()->getPrefixedDBkey(),
253 'default' =>
'history',
258 'label' => $this->
msg(
'date-range-to' )->text(),
259 'name' =>
'date-range-to',
262 'label-raw' => $this->
msg(
'tag-filter' )->parse(),
263 'type' =>
'tagfilter',
265 'name' =>
'tagfilter',
266 'value' => $tagFilter,
269 $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
270 if ( $permissionManager->userHasRight( $this->getUser(),
'deletedhistory' ) ) {
273 'label' => $this->
msg(
'history-show-deleted' )->text(),
274 'default' => $request->getBool(
'deleted' ),
284 ->setCollapsibleOptions(
true )
285 ->setId(
'mw-history-searchform' )
286 ->setSubmitText( $this->
msg(
'historyaction-submit' )->text() )
287 ->setWrapperAttributes( [
'id' =>
'mw-history-search' ] )
288 ->setWrapperLegend( $this->
msg(
'history-fieldset-title' )->text() );
289 $htmlForm->loadData();
291 $out->addHTML( $htmlForm->getHTML(
false ) );
296 $dateComponents = explode(
'-', $ts );
297 if ( count( $dateComponents ) > 1 ) {
298 $y = $dateComponents[0];
299 $m = $dateComponents[1];
300 $d = $dateComponents[2];
306 $pager =
new HistoryPager( $this, $y, $m, $tagFilter, $conds, $d );
308 $pager->getNavigationBar() .
310 $pager->getNavigationBar()
312 $out->preventClickjacking( $pager->getPreventClickjacking() );
322 $this->
getContext()->getConfig()->
get(
'ShowUpdatedMarker' ) &&
345 if ( $direction === self::DIR_PREV ) {
346 list(
$dirs, $oper ) = [
"ASC",
">=" ];
348 list(
$dirs, $oper ) = [
"DESC",
"<=" ];
352 $offsets = [
"rev_timestamp $oper " .
$dbr->addQuotes(
$dbr->timestamp( $offset ) ) ];
357 $page_id = $this->page->getId();
363 array_merge( [
'rev_page' => $page_id ], $offsets ),
366 'ORDER BY' =>
"rev_timestamp $dirs",
367 'USE INDEX' => [
'revision' =>
'page_timestamp' ],
385 $feedClasses = $this->context->getConfig()->get(
'FeedClasses' );
387 $feed =
new $feedClasses[
$type](
388 $this->
getTitle()->getPrefixedText() .
' - ' .
389 $this->
msg(
'history-feed-title' )->inContentLanguage()->text(),
390 $this->
msg(
'history-feed-description' )->inContentLanguage()->text(),
391 $this->
getTitle()->getFullURL(
'action=history' )
396 $limit = $request->getInt(
'limit', 10 );
399 $this->context->getConfig()->get(
'FeedLimit' )
406 if ( $items->numRows() ) {
407 foreach ( $items as $row ) {
408 $feed->outItem( $this->
feedItem( $row ) );
418 $this->
msg(
'nohistory' )->inContentLanguage()->text(),
419 $this->
msg(
'history-feed-empty' )->inContentLanguage()->parseAsBlock(),
423 $this->
getTitle()->getTalkPage()->getFullURL()
436 $revisionStore = MediaWikiServices::getInstance()->getRevisionStore();
437 $rev = $revisionStore->newRevisionFromRow( $row, 0, $this->
getTitle() );
438 $prevRev = $revisionStore->getPreviousRevision( $rev );
439 $revComment = $rev->getComment() ===
null ? null : $rev->getComment()->text;
442 $prevRev ? $prevRev->getId() :
false,
444 $rev->getTimestamp(),
447 $revUserText = $rev->getUser() ? $rev->getUser()->getName() :
'';
448 if ( $revComment ==
'' ) {
449 $contLang = MediaWikiServices::getInstance()->getContentLanguage();
450 $title = $this->
msg(
'history-feed-item-nocomment',
452 $contLang->timeanddate( $rev->getTimestamp() ),
453 $contLang->date( $rev->getTimestamp() ),
454 $contLang->time( $rev->getTimestamp() )
455 )->inContentLanguage()->text();
458 $this->
msg(
'colon-separator' )->inContentLanguage()->text() .
465 $this->
getTitle()->getFullURL(
'diff=' . $rev->getId() .
'&oldid=prev' ),
466 $rev->getTimestamp(),
468 $this->
getTitle()->getTalkPage()->getFullURL()