MediaWiki  1.23.0
HistoryAction.php
Go to the documentation of this file.
1 <?php
37  const DIR_PREV = 0;
38  const DIR_NEXT = 1;
39 
41  public $message;
42 
43  public function getName() {
44  return 'history';
45  }
46 
47  public function requiresWrite() {
48  return false;
49  }
50 
51  public function requiresUnblock() {
52  return false;
53  }
54 
55  protected function getPageTitle() {
56  return $this->msg( 'history-title', $this->getTitle()->getPrefixedText() )->text();
57  }
58 
59  protected function getDescription() {
60  // Creation of a subtitle link pointing to [[Special:Log]]
61  return Linker::linkKnown(
62  SpecialPage::getTitleFor( 'Log' ),
63  $this->msg( 'viewpagelogs' )->escaped(),
64  array(),
65  array( 'page' => $this->getTitle()->getPrefixedText() )
66  );
67  }
68 
73  public function getArticle() {
74  return $this->page;
75  }
76 
81  private function preCacheMessages() {
82  // Precache various messages
83  if ( !isset( $this->message ) ) {
84  $msgs = array( 'cur', 'last', 'pipe-separator' );
85  foreach ( $msgs as $msg ) {
86  $this->message[$msg] = $this->msg( $msg )->escaped();
87  }
88  }
89  }
90 
94  function onView() {
95  global $wgScript, $wgUseFileCache;
96 
97  $out = $this->getOutput();
98  $request = $this->getRequest();
99 
103  if ( $out->checkLastModified( $this->page->getTouched() ) ) {
104  return; // Client cache fresh and headers sent, nothing more to do.
105  }
106 
107  wfProfileIn( __METHOD__ );
108 
109  $this->preCacheMessages();
110 
111  # Fill in the file cache if not set already
112  if ( $wgUseFileCache && HTMLFileCache::useFileCache( $this->getContext() ) ) {
113  $cache = HTMLFileCache::newFromTitle( $this->getTitle(), 'history' );
114  if ( !$cache->isCacheGood( /* Assume up to date */ ) ) {
115  ob_start( array( &$cache, 'saveToFileCache' ) );
116  }
117  }
118 
119  // Setup page variables.
120  $out->setFeedAppendQuery( 'action=history' );
121  $out->addModules( 'mediawiki.action.history' );
122 
123  // Handle atom/RSS feeds.
124  $feedType = $request->getVal( 'feed' );
125  if ( $feedType ) {
126  $this->feed( $feedType );
127  wfProfileOut( __METHOD__ );
128 
129  return;
130  }
131 
132  // Fail nicely if article doesn't exist.
133  if ( !$this->page->exists() ) {
134  $out->addWikiMsg( 'nohistory' );
135  # show deletion/move log if there is an entry
137  $out,
138  array( 'delete', 'move' ),
139  $this->getTitle(),
140  '',
141  array( 'lim' => 10,
142  'conds' => array( "log_action != 'revision'" ),
143  'showIfEmpty' => false,
144  'msgKey' => array( 'moveddeleted-notice' )
145  )
146  );
147  wfProfileOut( __METHOD__ );
148 
149  return;
150  }
151 
155  $year = $request->getInt( 'year' );
156  $month = $request->getInt( 'month' );
157  $tagFilter = $request->getVal( 'tagfilter' );
158  $tagSelector = ChangeTags::buildTagFilterSelector( $tagFilter );
159 
163  if ( $request->getBool( 'deleted' ) ) {
164  $conds = array( 'rev_deleted != 0' );
165  } else {
166  $conds = array();
167  }
168  if ( $this->getUser()->isAllowed( 'deletedhistory' ) ) {
169  $checkDeleted = Xml::checkLabel( $this->msg( 'history-show-deleted' )->text(),
170  'deleted', 'mw-show-deleted-only', $request->getBool( 'deleted' ) ) . "\n";
171  } else {
172  $checkDeleted = '';
173  }
174 
175  // Add the general form
176  $action = htmlspecialchars( $wgScript );
177  $out->addHTML(
178  "<form action=\"$action\" method=\"get\" id=\"mw-history-searchform\">" .
180  $this->msg( 'history-fieldset-title' )->text(),
181  false,
182  array( 'id' => 'mw-history-search' )
183  ) .
184  Html::hidden( 'title', $this->getTitle()->getPrefixedDBkey() ) . "\n" .
185  Html::hidden( 'action', 'history' ) . "\n" .
187  ( $year == null ? MWTimestamp::getLocalInstance()->format( 'Y' ) : $year ),
188  $month
189  ) . '&#160;' .
190  ( $tagSelector ? ( implode( '&#160;', $tagSelector ) . '&#160;' ) : '' ) .
191  $checkDeleted .
192  Xml::submitButton( $this->msg( 'allpagessubmit' )->text() ) . "\n" .
193  '</fieldset></form>'
194  );
195 
196  wfRunHooks( 'PageHistoryBeforeList', array( &$this->page, $this->getContext() ) );
197 
198  // Create and output the list.
199  $pager = new HistoryPager( $this, $year, $month, $tagFilter, $conds );
200  $out->addHTML(
201  $pager->getNavigationBar() .
202  $pager->getBody() .
203  $pager->getNavigationBar()
204  );
205  $out->preventClickjacking( $pager->getPreventClickjacking() );
206 
207  wfProfileOut( __METHOD__ );
208  }
209 
220  function fetchRevisions( $limit, $offset, $direction ) {
221  // Fail if article doesn't exist.
222  if ( !$this->getTitle()->exists() ) {
223  return new FakeResultWrapper( array() );
224  }
225 
226  $dbr = wfGetDB( DB_SLAVE );
227 
228  if ( $direction == HistoryPage::DIR_PREV ) {
229  list( $dirs, $oper ) = array( "ASC", ">=" );
230  } else { /* $direction == HistoryPage::DIR_NEXT */
231  list( $dirs, $oper ) = array( "DESC", "<=" );
232  }
233 
234  if ( $offset ) {
235  $offsets = array( "rev_timestamp $oper " . $dbr->addQuotes( $dbr->timestamp( $offset ) ) );
236  } else {
237  $offsets = array();
238  }
239 
240  $page_id = $this->page->getId();
241 
242  return $dbr->select( 'revision',
244  array_merge( array( 'rev_page' => $page_id ), $offsets ),
245  __METHOD__,
246  array( 'ORDER BY' => "rev_timestamp $dirs",
247  'USE INDEX' => 'page_timestamp', 'LIMIT' => $limit )
248  );
249  }
250 
256  function feed( $type ) {
257  global $wgFeedClasses, $wgFeedLimit;
258  if ( !FeedUtils::checkFeedOutput( $type ) ) {
259  return;
260  }
261  $request = $this->getRequest();
262 
264  $feed = new $wgFeedClasses[$type](
265  $this->getTitle()->getPrefixedText() . ' - ' .
266  $this->msg( 'history-feed-title' )->inContentLanguage()->text(),
267  $this->msg( 'history-feed-description' )->inContentLanguage()->text(),
268  $this->getTitle()->getFullURL( 'action=history' )
269  );
270 
271  // Get a limit on number of feed entries. Provide a sane default
272  // of 10 if none is defined (but limit to $wgFeedLimit max)
273  $limit = $request->getInt( 'limit', 10 );
274  $limit = min( max( $limit, 1 ), $wgFeedLimit );
275 
276  $items = $this->fetchRevisions( $limit, 0, HistoryPage::DIR_NEXT );
277 
278  // Generate feed elements enclosed between header and footer.
279  $feed->outHeader();
280  if ( $items->numRows() ) {
281  foreach ( $items as $row ) {
282  $feed->outItem( $this->feedItem( $row ) );
283  }
284  } else {
285  $feed->outItem( $this->feedEmpty() );
286  }
287  $feed->outFooter();
288  }
289 
290  function feedEmpty() {
291  return new FeedItem(
292  $this->msg( 'nohistory' )->inContentLanguage()->text(),
293  $this->msg( 'history-feed-empty' )->inContentLanguage()->parseAsBlock(),
294  $this->getTitle()->getFullURL(),
295  wfTimestamp( TS_MW ),
296  '',
297  $this->getTitle()->getTalkPage()->getFullURL()
298  );
299  }
300 
309  function feedItem( $row ) {
310  $rev = new Revision( $row );
311  $rev->setTitle( $this->getTitle() );
312  $text = FeedUtils::formatDiffRow(
313  $this->getTitle(),
314  $this->getTitle()->getPreviousRevisionID( $rev->getId() ),
315  $rev->getId(),
316  $rev->getTimestamp(),
317  $rev->getComment()
318  );
319  if ( $rev->getComment() == '' ) {
321  $title = $this->msg( 'history-feed-item-nocomment',
322  $rev->getUserText(),
323  $wgContLang->timeanddate( $rev->getTimestamp() ),
324  $wgContLang->date( $rev->getTimestamp() ),
325  $wgContLang->time( $rev->getTimestamp() ) )->inContentLanguage()->text();
326  } else {
327  $title = $rev->getUserText() .
328  $this->msg( 'colon-separator' )->inContentLanguage()->text() .
329  FeedItem::stripComment( $rev->getComment() );
330  }
331 
332  return new FeedItem(
333  $title,
334  $text,
335  $this->getTitle()->getFullURL( 'diff=' . $rev->getId() . '&oldid=prev' ),
336  $rev->getTimestamp(),
337  $rev->getUserText(),
338  $this->getTitle()->getTalkPage()->getFullURL()
339  );
340  }
341 }
342 
351  public $lastRow = false;
352 
354 
355  protected $oldIdChecked;
356 
357  protected $preventClickjacking = false;
361  protected $parentLens;
362 
370  function __construct( $historyPage, $year = '', $month = '', $tagFilter = '', $conds = array() ) {
371  parent::__construct( $historyPage->getContext() );
372  $this->historyPage = $historyPage;
373  $this->tagFilter = $tagFilter;
374  $this->getDateCond( $year, $month );
375  $this->conds = $conds;
376  }
377 
378  // For hook compatibility...
379  function getArticle() {
380  return $this->historyPage->getArticle();
381  }
382 
383  function getSqlComment() {
384  if ( $this->conds ) {
385  return 'history page filtered'; // potentially slow, see CR r58153
386  } else {
387  return 'history page unfiltered';
388  }
389  }
390 
391  function getQueryInfo() {
392  $queryInfo = array(
393  'tables' => array( 'revision', 'user' ),
394  'fields' => array_merge( Revision::selectFields(), Revision::selectUserFields() ),
395  'conds' => array_merge(
396  array( 'rev_page' => $this->getWikiPage()->getId() ),
397  $this->conds ),
398  'options' => array( 'USE INDEX' => array( 'revision' => 'page_timestamp' ) ),
399  'join_conds' => array( 'user' => Revision::userJoinCond() ),
400  );
402  $queryInfo['tables'],
403  $queryInfo['fields'],
404  $queryInfo['conds'],
405  $queryInfo['join_conds'],
406  $queryInfo['options'],
407  $this->tagFilter
408  );
409  wfRunHooks( 'PageHistoryPager::getQueryInfo', array( &$this, &$queryInfo ) );
410 
411  return $queryInfo;
412  }
413 
414  function getIndexField() {
415  return 'rev_timestamp';
416  }
417 
422  function formatRow( $row ) {
423  if ( $this->lastRow ) {
424  $latest = ( $this->counter == 1 && $this->mIsFirst );
425  $firstInList = $this->counter == 1;
426  $this->counter++;
427  $s = $this->historyLine( $this->lastRow, $row,
428  $this->getTitle()->getNotificationTimestamp( $this->getUser() ), $latest, $firstInList );
429  } else {
430  $s = '';
431  }
432  $this->lastRow = $row;
433 
434  return $s;
435  }
436 
437  function doBatchLookups() {
438  # Do a link batch query
439  $this->mResult->seek( 0 );
440  $batch = new LinkBatch();
441  $revIds = array();
442  foreach ( $this->mResult as $row ) {
443  if ( $row->rev_parent_id ) {
444  $revIds[] = $row->rev_parent_id;
445  }
446  if ( !is_null( $row->user_name ) ) {
447  $batch->add( NS_USER, $row->user_name );
448  $batch->add( NS_USER_TALK, $row->user_name );
449  } else { # for anons or usernames of imported revisions
450  $batch->add( NS_USER, $row->rev_user_text );
451  $batch->add( NS_USER_TALK, $row->rev_user_text );
452  }
453  }
454  $this->parentLens = Revision::getParentLengths( $this->mDb, $revIds );
455  $batch->execute();
456  $this->mResult->seek( 0 );
457  }
458 
464  function getStartBody() {
465  global $wgScript;
466  $this->lastRow = false;
467  $this->counter = 1;
468  $this->oldIdChecked = 0;
469 
470  $this->getOutput()->wrapWikiMsg( "<div class='mw-history-legend'>\n$1\n</div>", 'histlegend' );
471  $s = Html::openElement( 'form', array( 'action' => $wgScript,
472  'id' => 'mw-history-compare' ) ) . "\n";
473  $s .= Html::hidden( 'title', $this->getTitle()->getPrefixedDBkey() ) . "\n";
474  $s .= Html::hidden( 'action', 'historysubmit' ) . "\n";
475 
476  // Button container stored in $this->buttons for re-use in getEndBody()
477  $this->buttons = '<div>';
478  $this->buttons .= $this->submitButton( $this->msg( 'compareselectedversions' )->text(),
479  array( 'class' => 'historysubmit mw-history-compareselectedversions-button' )
480  + Linker::tooltipAndAccesskeyAttribs( 'compareselectedversions' )
481  ) . "\n";
482 
483  if ( $this->getUser()->isAllowed( 'deleterevision' ) ) {
484  $this->buttons .= $this->getRevisionButton( 'revisiondelete', 'showhideselectedversions' );
485  }
486  $this->buttons .= '</div>';
487 
488  $s .= $this->buttons;
489  $s .= '<ul id="pagehistory">' . "\n";
490 
491  return $s;
492  }
493 
494  private function getRevisionButton( $name, $msg ) {
495  $this->preventClickjacking();
496  # Note bug #20966, <button> is non-standard in IE<8
497  $element = Html::element(
498  'button',
499  array(
500  'type' => 'submit',
501  'name' => $name,
502  'value' => '1',
503  'class' => "historysubmit mw-history-$name-button",
504  ),
505  $this->msg( $msg )->text()
506  ) . "\n";
507  return $element;
508  }
509 
510  function getEndBody() {
511  if ( $this->lastRow ) {
512  $latest = $this->counter == 1 && $this->mIsFirst;
513  $firstInList = $this->counter == 1;
514  if ( $this->mIsBackwards ) {
515  # Next row is unknown, but for UI reasons, probably exists if an offset has been specified
516  if ( $this->mOffset == '' ) {
517  $next = null;
518  } else {
519  $next = 'unknown';
520  }
521  } else {
522  # The next row is the past-the-end row
523  $next = $this->mPastTheEndRow;
524  }
525  $this->counter++;
526  $s = $this->historyLine( $this->lastRow, $next,
527  $this->getTitle()->getNotificationTimestamp( $this->getUser() ), $latest, $firstInList );
528  } else {
529  $s = '';
530  }
531  $s .= "</ul>\n";
532  # Add second buttons only if there is more than one rev
533  if ( $this->getNumRows() > 2 ) {
534  $s .= $this->buttons;
535  }
536  $s .= '</form>';
537 
538  return $s;
539  }
540 
548  function submitButton( $message, $attributes = array() ) {
549  # Disable submit button if history has 1 revision only
550  if ( $this->getNumRows() > 1 ) {
551  return Xml::submitButton( $message, $attributes );
552  } else {
553  return '';
554  }
555  }
556 
571  function historyLine( $row, $next, $notificationtimestamp = false,
572  $latest = false, $firstInList = false ) {
573  $rev = new Revision( $row );
574  $rev->setTitle( $this->getTitle() );
575 
576  if ( is_object( $next ) ) {
577  $prevRev = new Revision( $next );
578  $prevRev->setTitle( $this->getTitle() );
579  } else {
580  $prevRev = null;
581  }
582 
583  $curlink = $this->curLink( $rev, $latest );
584  $lastlink = $this->lastLink( $rev, $next );
585  $curLastlinks = $curlink . $this->historyPage->message['pipe-separator'] . $lastlink;
586  $histLinks = Html::rawElement(
587  'span',
588  array( 'class' => 'mw-history-histlinks' ),
589  $this->msg( 'parentheses' )->rawParams( $curLastlinks )->escaped()
590  );
591 
592  $diffButtons = $this->diffButtons( $rev, $firstInList );
593  $s = $histLinks . $diffButtons;
594 
595  $link = $this->revLink( $rev );
596  $classes = array();
597 
598  $del = '';
599  $user = $this->getUser();
600  // Show checkboxes for each revision
601  if ( $user->isAllowed( 'deleterevision' ) ) {
602  $this->preventClickjacking();
603  // If revision was hidden from sysops, disable the checkbox
604  if ( !$rev->userCan( Revision::DELETED_RESTRICTED, $user ) ) {
605  $del = Xml::check( 'deleterevisions', false, array( 'disabled' => 'disabled' ) );
606  // Otherwise, enable the checkbox...
607  } else {
608  $del = Xml::check( 'showhiderevisions', false,
609  array( 'name' => 'ids[' . $rev->getId() . ']' ) );
610  }
611  // User can only view deleted revisions...
612  } elseif ( $rev->getVisibility() && $user->isAllowed( 'deletedhistory' ) ) {
613  // If revision was hidden from sysops, disable the link
614  if ( !$rev->userCan( Revision::DELETED_RESTRICTED, $user ) ) {
615  $del = Linker::revDeleteLinkDisabled( false );
616  // Otherwise, show the link...
617  } else {
618  $query = array( 'type' => 'revision',
619  'target' => $this->getTitle()->getPrefixedDBkey(), 'ids' => $rev->getId() );
620  $del .= Linker::revDeleteLink( $query,
621  $rev->isDeleted( Revision::DELETED_RESTRICTED ), false );
622  }
623  }
624  if ( $del ) {
625  $s .= " $del ";
626  }
627 
628  $lang = $this->getLanguage();
629  $dirmark = $lang->getDirMark();
630 
631  $s .= " $link";
632  $s .= $dirmark;
633  $s .= " <span class='history-user'>" .
634  Linker::revUserTools( $rev, true ) . "</span>";
635  $s .= $dirmark;
636 
637  if ( $rev->isMinor() ) {
638  $s .= ' ' . ChangesList::flag( 'minor' );
639  }
640 
641  # Sometimes rev_len isn't populated
642  if ( $rev->getSize() !== null ) {
643  # Size is always public data
644  $prevSize = isset( $this->parentLens[$row->rev_parent_id] )
645  ? $this->parentLens[$row->rev_parent_id]
646  : 0;
647  $sDiff = ChangesList::showCharacterDifference( $prevSize, $rev->getSize() );
648  $fSize = Linker::formatRevisionSize( $rev->getSize() );
649  $s .= ' <span class="mw-changeslist-separator">. .</span> ' . "$fSize $sDiff";
650  }
651 
652  # Text following the character difference is added just before running hooks
653  $s2 = Linker::revComment( $rev, false, true );
654 
655  if ( $notificationtimestamp && ( $row->rev_timestamp >= $notificationtimestamp ) ) {
656  $s2 .= ' <span class="updatedmarker">' . $this->msg( 'updatedmarker' )->escaped() . '</span>';
657  $classes[] = 'mw-history-line-updated';
658  }
659 
660  $tools = array();
661 
662  # Rollback and undo links
663  if ( $prevRev && $this->getTitle()->quickUserCan( 'edit', $user ) ) {
664  if ( $latest && $this->getTitle()->quickUserCan( 'rollback', $user ) ) {
665  // Get a rollback link without the brackets
666  $rollbackLink = Linker::generateRollback(
667  $rev,
668  $this->getContext(),
669  array( 'verify', 'noBrackets' )
670  );
671  if ( $rollbackLink ) {
672  $this->preventClickjacking();
673  $tools[] = $rollbackLink;
674  }
675  }
676 
677  if ( !$rev->isDeleted( Revision::DELETED_TEXT )
678  && !$prevRev->isDeleted( Revision::DELETED_TEXT )
679  ) {
680  # Create undo tooltip for the first (=latest) line only
681  $undoTooltip = $latest
682  ? array( 'title' => $this->msg( 'tooltip-undo' )->text() )
683  : array();
684  $undolink = Linker::linkKnown(
685  $this->getTitle(),
686  $this->msg( 'editundo' )->escaped(),
687  $undoTooltip,
688  array(
689  'action' => 'edit',
690  'undoafter' => $prevRev->getId(),
691  'undo' => $rev->getId()
692  )
693  );
694  $tools[] = "<span class=\"mw-history-undo\">{$undolink}</span>";
695  }
696  }
697  // Allow extension to add their own links here
698  wfRunHooks( 'HistoryRevisionTools', array( $rev, &$tools ) );
699 
700  if ( $tools ) {
701  $s2 .= ' ' . $this->msg( 'parentheses' )->rawParams( $lang->pipeList( $tools ) )->escaped();
702  }
703 
704  # Tags
705  list( $tagSummary, $newClasses ) = ChangeTags::formatSummaryRow( $row->ts_tags, 'history' );
706  $classes = array_merge( $classes, $newClasses );
707  if ( $tagSummary !== '' ) {
708  $s2 .= " $tagSummary";
709  }
710 
711  # Include separator between character difference and following text
712  if ( $s2 !== '' ) {
713  $s .= ' <span class="mw-changeslist-separator">. .</span> ' . $s2;
714  }
715 
716  wfRunHooks( 'PageHistoryLineEnding', array( $this, &$row, &$s, &$classes ) );
717 
718  $attribs = array();
719  if ( $classes ) {
720  $attribs['class'] = implode( ' ', $classes );
721  }
722 
723  return Xml::tags( 'li', $attribs, $s ) . "\n";
724  }
725 
732  function revLink( $rev ) {
733  $date = $this->getLanguage()->userTimeAndDate( $rev->getTimestamp(), $this->getUser() );
734  $date = htmlspecialchars( $date );
735  if ( $rev->userCan( Revision::DELETED_TEXT, $this->getUser() ) ) {
737  $this->getTitle(),
738  $date,
739  array( 'class' => 'mw-changeslist-date' ),
740  array( 'oldid' => $rev->getId() )
741  );
742  } else {
743  $link = $date;
744  }
745  if ( $rev->isDeleted( Revision::DELETED_TEXT ) ) {
746  $link = "<span class=\"history-deleted\">$link</span>";
747  }
748 
749  return $link;
750  }
751 
759  function curLink( $rev, $latest ) {
760  $cur = $this->historyPage->message['cur'];
761  if ( $latest || !$rev->userCan( Revision::DELETED_TEXT, $this->getUser() ) ) {
762  return $cur;
763  } else {
764  return Linker::linkKnown(
765  $this->getTitle(),
766  $cur,
767  array(),
768  array(
769  'diff' => $this->getWikiPage()->getLatest(),
770  'oldid' => $rev->getId()
771  )
772  );
773  }
774  }
775 
783  function lastLink( $prevRev, $next ) {
784  $last = $this->historyPage->message['last'];
785  # $next may either be a Row, null, or "unkown"
786  $nextRev = is_object( $next ) ? new Revision( $next ) : $next;
787  if ( is_null( $next ) ) {
788  # Probably no next row
789  return $last;
790  } elseif ( $next === 'unknown' ) {
791  # Next row probably exists but is unknown, use an oldid=prev link
792  return Linker::linkKnown(
793  $this->getTitle(),
794  $last,
795  array(),
796  array(
797  'diff' => $prevRev->getId(),
798  'oldid' => 'prev'
799  )
800  );
801  } elseif ( !$prevRev->userCan( Revision::DELETED_TEXT, $this->getUser() )
802  || !$nextRev->userCan( Revision::DELETED_TEXT, $this->getUser() )
803  ) {
804  return $last;
805  } else {
806  return Linker::linkKnown(
807  $this->getTitle(),
808  $last,
809  array(),
810  array(
811  'diff' => $prevRev->getId(),
812  'oldid' => $next->rev_id
813  )
814  );
815  }
816  }
817 
826  function diffButtons( $rev, $firstInList ) {
827  if ( $this->getNumRows() > 1 ) {
828  $id = $rev->getId();
829  $radio = array( 'type' => 'radio', 'value' => $id );
831  if ( $firstInList ) {
832  $first = Xml::element( 'input',
833  array_merge( $radio, array(
834  'style' => 'visibility:hidden',
835  'name' => 'oldid',
836  'id' => 'mw-oldid-null' ) )
837  );
838  $checkmark = array( 'checked' => 'checked' );
839  } else {
840  # Check visibility of old revisions
841  if ( !$rev->userCan( Revision::DELETED_TEXT, $this->getUser() ) ) {
842  $radio['disabled'] = 'disabled';
843  $checkmark = array(); // We will check the next possible one
844  } elseif ( !$this->oldIdChecked ) {
845  $checkmark = array( 'checked' => 'checked' );
846  $this->oldIdChecked = $id;
847  } else {
848  $checkmark = array();
849  }
850  $first = Xml::element( 'input',
851  array_merge( $radio, $checkmark, array(
852  'name' => 'oldid',
853  'id' => "mw-oldid-$id" ) ) );
854  $checkmark = array();
855  }
856  $second = Xml::element( 'input',
857  array_merge( $radio, $checkmark, array(
858  'name' => 'diff',
859  'id' => "mw-diff-$id" ) ) );
860 
861  return $first . $second;
862  } else {
863  return '';
864  }
865  }
866 
870  function preventClickjacking( $enable = true ) {
871  $this->preventClickjacking = $enable;
872  }
873 
878  function getPreventClickjacking() {
880  }
881 }
882 
886 class HistoryPage extends HistoryAction {
887  // @codingStandardsIgnoreStart Needed "useless" override to make it public.
888  public function __construct( Page $article ) {
889  parent::__construct( $article );
890  }
891  // @codingStandardsIgnoreEnd
892 
893  public function history() {
894  $this->onView();
895  }
896 }
HistoryPage
Backwards-compatibility alias.
Definition: HistoryAction.php:883
HistoryAction\$message
array $message
Array of message keys and strings *.
Definition: HistoryAction.php:40
Xml\checkLabel
static checkLabel( $label, $name, $id, $checked=false, $attribs=array())
Convenience function to build an HTML checkbox with a label.
Definition: Xml.php:433
FakeResultWrapper
Overloads the relevant methods of the real ResultsWrapper so it doesn't go anywhere near an actual da...
Definition: DatabaseUtility.php:230
Page
Abstract class for type hinting (accepts WikiPage, Article, ImagePage, CategoryPage)
Definition: WikiPage.php:26
Revision\DELETED_RESTRICTED
const DELETED_RESTRICTED
Definition: Revision.php:68
Linker\generateRollback
static generateRollback( $rev, IContextSource $context=null, $options=array( 'verify'))
Generate a rollback link for a given revision.
Definition: Linker.php:1770
FeedItem
A base class for basic support for outputting syndication feeds in RSS and other formats.
Definition: Feed.php:38
ContextSource\getContext
getContext()
Get the RequestContext object.
Definition: ContextSource.php:40
of
globals txt Globals are evil The original MediaWiki code relied on globals for processing context far too often MediaWiki development since then has been a story of slowly moving context out of global variables and into objects Storing processing context in object member variables allows those objects to be reused in a much more flexible way Consider the elegance of
Definition: globals.txt:10
Linker\revDeleteLink
static revDeleteLink( $query=array(), $restricted=false, $delete=true)
Creates a (show/hide) link for deleting revisions/log entries.
Definition: Linker.php:2196
php
skin txt MediaWiki includes four core it has been set as the default in MediaWiki since the replacing Monobook it had been been the default skin since before being replaced by Vector largely rewritten in while keeping its appearance Several legacy skins were removed in the as the burden of supporting them became too heavy to bear Those in etc for skin dependent CSS etc for skin dependent JavaScript These can also be customised on a per user by etc This feature has led to a wide variety of user styles becoming that gallery is a good place to ending in php
Definition: skin.txt:62
HistoryPager\$counter
$counter
Definition: HistoryAction.php:351
HistoryPager\$parentLens
array $parentLens
Definition: HistoryAction.php:358
IndexPager\$mIsFirst
$mIsFirst
True if the current result set is the first one.
Definition: Pager.php:116
ContextSource\msg
msg()
Get a Message object with context set Parameters are the same as wfMessage()
Definition: ContextSource.php:175
LinkBatch
Class representing a list of titles The execute() method checks them all for existence and adds them ...
Definition: LinkBatch.php:30
Xml\tags
static tags( $element, $attribs=null, $contents)
Same as Xml::element(), but does not escape contents.
Definition: Xml.php:131
HistoryPager\getPreventClickjacking
getPreventClickjacking()
Get the "prevent clickjacking" flag.
Definition: HistoryAction.php:875
FormlessAction
An action which just does something, without showing a form first.
Definition: FormlessAction.php:29
Action\getRequest
getRequest()
Get the WebRequest being used for this instance.
Definition: Action.php:182
HistoryAction\onView
onView()
Print the history page for an article.
Definition: HistoryAction.php:93
HistoryAction\feedItem
feedItem( $row)
Generate a FeedItem object from a given revision table row Borrows Recent Changes' feed generation fu...
Definition: HistoryAction.php:308
HistoryPager\diffButtons
diffButtons( $rev, $firstInList)
Create radio buttons for page history.
Definition: HistoryAction.php:823
HistoryAction\requiresWrite
requiresWrite()
Whether this action requires the wiki not to be locked.
Definition: HistoryAction.php:46
HistoryPager\getArticle
getArticle()
Definition: HistoryAction.php:376
$last
$last
Definition: profileinfo.php:365
wfGetDB
& wfGetDB( $db, $groups=array(), $wiki=false)
Get a Database object.
Definition: GlobalFunctions.php:3650
text
design txt This is a brief overview of the new design More thorough and up to date information is available on the documentation wiki at etc Handles the details of getting and saving to the user table of the and dealing with sessions and cookies OutputPage Encapsulates the entire HTML page that will be sent in response to any server request It is used by calling its functions to add text
Definition: design.txt:12
HistoryAction\getPageTitle
getPageTitle()
Returns the name that goes in the <h1> page title.
Definition: HistoryAction.php:54
wfTimestamp
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Definition: GlobalFunctions.php:2483
HistoryAction\DIR_NEXT
const DIR_NEXT
Definition: HistoryAction.php:38
FeedUtils\formatDiffRow
static formatDiffRow( $title, $oldid, $newid, $timestamp, $comment, $actiontext='')
Really format a diff for the newsfeed.
Definition: FeedUtils.php:105
wfProfileIn
wfProfileIn( $functionname)
Begin profiling of a function.
Definition: Profiler.php:33
FeedItem\stripComment
static stripComment( $text)
Quickie hack...
Definition: Feed.php:175
$limit
if( $sleep) $limit
Definition: importImages.php:99
ChangeTags\buildTagFilterSelector
static buildTagFilterSelector( $selected='', $fullForm=false, Title $title=null)
Build a text box to select a change tag.
Definition: ChangeTags.php:250
HistoryPager\submitButton
submitButton( $message, $attributes=array())
Creates a submit button.
Definition: HistoryAction.php:545
HistoryPager\getRevisionButton
getRevisionButton( $name, $msg)
Definition: HistoryAction.php:491
HistoryAction\fetchRevisions
fetchRevisions( $limit, $offset, $direction)
Fetch an array of revisions, specified by a given limit, offset and direction.
Definition: HistoryAction.php:219
$s
$s
Definition: mergeMessageFileList.php:156
SpecialPage\getTitleFor
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name.
Definition: SpecialPage.php:74
Html\hidden
static hidden( $name, $value, $attribs=array())
Convenience function to produce an input element with type=hidden.
Definition: Html.php:662
$wgContLang
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as and the content language as $wgContLang
Definition: design.txt:56
HistoryAction\getDescription
getDescription()
Returns the description that goes below the <h1> tag.
Definition: HistoryAction.php:58
HistoryPager\$conds
$conds
Definition: HistoryAction.php:351
ContextSource\getUser
getUser()
Get the User object.
Definition: ContextSource.php:132
$link
set to $title object and return false for a match for latest after cache objects are set use the ContentHandler facility to handle CSS and JavaScript for highlighting & $link
Definition: hooks.txt:2149
ContextSource\getTitle
getTitle()
Get the Title object.
Definition: ContextSource.php:87
Linker\linkKnown
static linkKnown( $target, $html=null, $customAttribs=array(), $query=array(), $options=array( 'known', 'noclasses'))
Identical to link(), except $options defaults to 'known'.
Definition: Linker.php:264
ChangesList\flag
static flag( $flag)
Provide the "<abbr>" element appropriate to a given abbreviated flag, namely the flag indicating a ne...
Definition: ChangesList.php:132
$dbr
$dbr
Definition: testCompression.php:48
ContextSource\getLanguage
getLanguage()
Get the Language object.
Definition: ContextSource.php:154
HistoryPager\$historyPage
$historyPage
Definition: HistoryAction.php:351
Revision
Definition: Revision.php:26
HistoryPager\$lastRow
bool stdClass $lastRow
Definition: HistoryAction.php:349
HistoryPager\historyLine
historyLine( $row, $next, $notificationtimestamp=false, $latest=false, $firstInList=false)
Returns a row from the history printout.
Definition: HistoryAction.php:568
Linker\tooltipAndAccesskeyAttribs
static tooltipAndAccesskeyAttribs( $name)
Returns the attributes for the tooltip and access key.
Definition: Linker.php:2298
Action\getContext
getContext()
Get the IContextSource in use here.
Definition: Action.php:164
Html\openElement
static openElement( $element, $attribs=array())
Identical to rawElement(), but has no third parameter and omits the end tag (and the self-closing '/'...
Definition: Html.php:166
$out
$out
Definition: UtfNormalGenerate.php:167
ChangeTags\modifyDisplayQuery
static modifyDisplayQuery(&$tables, &$fields, &$conds, &$join_conds, &$options, $filter_tag=false)
Applies all tags-related changes to a query.
Definition: ChangeTags.php:202
HistoryPager\preventClickjacking
preventClickjacking( $enable=true)
This is called if a write operation is possible from the generated HTML.
Definition: HistoryAction.php:867
HistoryPager\doBatchLookups
doBatchLookups()
Called from getBody(), before getStartBody() is called and after doQuery() was called.
Definition: HistoryAction.php:434
HistoryPager\$buttons
$buttons
Definition: HistoryAction.php:351
Html\element
static element( $element, $attribs=array(), $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:148
HistoryAction
This class handles printing the history page for an article.
Definition: HistoryAction.php:36
HTMLFileCache\useFileCache
static useFileCache(IContextSource $context)
Check if pages can be cached for this request/user.
Definition: HTMLFileCache.php:90
HistoryAction\preCacheMessages
preCacheMessages()
As we use the same small set of messages in various methods and that they are called often,...
Definition: HistoryAction.php:80
Linker\revUserTools
static revUserTools( $rev, $isPublic=false)
Generate a user tool link cluster if the current user is allowed to view it.
Definition: Linker.php:1219
HistoryAction\feedEmpty
feedEmpty()
Definition: HistoryAction.php:289
ContextSource\getOutput
getOutput()
Get the OutputPage object.
Definition: ContextSource.php:122
HistoryPager\getSqlComment
getSqlComment()
Get some text to go in brackets in the "function name" part of the SQL comment.
Definition: HistoryAction.php:380
ContextSource\getWikiPage
getWikiPage()
Get the WikiPage object.
Definition: ContextSource.php:112
HistoryPager\$oldIdChecked
$oldIdChecked
Definition: HistoryAction.php:353
HistoryPager\curLink
curLink( $rev, $latest)
Create a diff-to-current link for this revision for this page.
Definition: HistoryAction.php:756
wfProfileOut
wfProfileOut( $functionname='missing')
Stop profiling of a function.
Definition: Profiler.php:46
Xml\element
static element( $element, $attribs=null, $contents='', $allowShortTag=true)
Format an XML element with given attributes and, optionally, text content.
Definition: Xml.php:39
wfRunHooks
wfRunHooks( $event, array $args=array(), $deprecatedVersion=null)
Call hook functions defined in $wgHooks.
Definition: GlobalFunctions.php:4001
IndexPager\$mPastTheEndRow
$mPastTheEndRow
Definition: Pager.php:86
HistoryPager\getIndexField
getIndexField()
This function should be overridden to return the name of the index fi- eld.
Definition: HistoryAction.php:411
Linker\revDeleteLinkDisabled
static revDeleteLinkDisabled( $delete=true)
Creates a dead (show/hide) link for deleting revisions/log entries.
Definition: Linker.php:2213
array
the array() calling protocol came about after MediaWiki 1.4rc1.
List of Api Query prop modules.
HistoryPager
Definition: HistoryAction.php:346
$dirs
$dirs
Definition: mergeMessageFileList.php:163
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:93
HistoryPager\formatRow
formatRow( $row)
Definition: HistoryAction.php:419
list
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
Definition: deferred.txt:11
false
processing should stop and the error should be shown to the user * false
Definition: hooks.txt:188
HistoryPage\__construct
__construct(Page $article)
Definition: HistoryAction.php:885
HistoryPager\__construct
__construct( $historyPage, $year='', $month='', $tagFilter='', $conds=array())
Definition: HistoryAction.php:367
TS_MW
const TS_MW
MediaWiki concatenated string timestamp (YYYYMMDDHHMMSS)
Definition: GlobalFunctions.php:2431
Action\getUser
getUser()
Shortcut to get the User being used for this instance.
Definition: Action.php:200
Linker\revComment
static revComment(Revision $rev, $local=false, $isPublic=false)
Wrap and format the given revision's comment block, if the current user is allowed to view it.
Definition: Linker.php:1578
$title
presenting them properly to the user as errors is done by the caller $title
Definition: hooks.txt:1324
NS_USER_TALK
const NS_USER_TALK
Definition: Defines.php:82
$name
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:336
HistoryPager\getEndBody
getEndBody()
Hook into getBody() for the end of the list.
Definition: HistoryAction.php:507
Xml\check
static check( $name, $checked=false, $attribs=array())
Convenience function to build an HTML checkbox.
Definition: Xml.php:339
Revision\getParentLengths
static getParentLengths( $db, array $revIds)
Do a batched query to get the parent revision lengths.
Definition: Revision.php:503
HistoryPager\$preventClickjacking
$preventClickjacking
Definition: HistoryAction.php:355
$tools
static configuration should be added through ResourceLoaderGetConfigVars instead can be used to get the real title after the basic globals have been set but before ordinary actions take place change it to the message you want to define which works for all SkinTemplate type skins $tools
Definition: hooks.txt:1679
HistoryPager\revLink
revLink( $rev)
Create a link to view this revision of the page.
Definition: HistoryAction.php:729
HTMLFileCache\newFromTitle
static newFromTitle( $title, $action)
Construct an ObjectFileCache from a Title and an action.
Definition: HTMLFileCache.php:39
Linker\formatRevisionSize
static formatRevisionSize( $size)
Definition: Linker.php:1600
ChangesList\showCharacterDifference
static showCharacterDifference( $old, $new, IContextSource $context=null)
Show formatted char difference.
Definition: ChangesList.php:189
HistoryPager\getQueryInfo
getQueryInfo()
This function should be overridden to provide all parameters needed for the main paged query.
Definition: HistoryAction.php:388
Action\getTitle
getTitle()
Shortcut to get the Title object from the page.
Definition: Action.php:237
$user
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a account $user
Definition: hooks.txt:237
HistoryAction\getName
getName()
Return the name of the action this object responds to.
Definition: HistoryAction.php:42
Action\msg
msg()
Get a Message object with context set Parameters are the same as wfMessage()
Definition: Action.php:247
$rev
presenting them properly to the user as errors is done by the caller return true use this to change the list i e etc $rev
Definition: hooks.txt:1337
DB_SLAVE
const DB_SLAVE
Definition: Defines.php:55
Action\exists
static exists( $name)
Check if a given action is recognised, even if it's disabled.
Definition: Action.php:156
$cache
$cache
Definition: mcc.php:32
Action\$page
WikiPage Article ImagePage CategoryPage Page $page
Page on which we're performing the action $page.
Definition: Action.php:42
HistoryAction\requiresUnblock
requiresUnblock()
Whether this action can still be executed by a blocked user.
Definition: HistoryAction.php:50
format
if the prop value should be in the metadata multi language array format
Definition: hooks.txt:1230
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
Xml\dateMenu
static dateMenu( $year, $month)
Definition: Xml.php:188
Revision\userJoinCond
static userJoinCond()
Return the value of a select() JOIN conds array for the user table.
Definition: Revision.php:386
HistoryAction\feed
feed( $type)
Output a subscription feed listing recent edits to this page.
Definition: HistoryAction.php:255
HistoryPage\history
history()
Definition: HistoryAction.php:890
NS_USER
const NS_USER
Definition: Defines.php:81
$batch
$batch
Definition: linkcache.txt:23
Action\getOutput
getOutput()
Get the OutputPage being used for this instance.
Definition: Action.php:191
Xml\submitButton
static submitButton( $value, $attribs=array())
Convenience function to build an HTML submit button.
Definition: Xml.php:463
ReverseChronologicalPager
IndexPager with a formatted navigation bar.
Definition: Pager.php:829
FeedUtils\checkFeedOutput
static checkFeedOutput( $type)
Check whether feeds can be used and that $type is a valid feed type.
Definition: FeedUtils.php:54
Revision\selectUserFields
static selectUserFields()
Return the list of user fields that should be selected from user table.
Definition: Revision.php:493
HistoryPager\getStartBody
getStartBody()
Creates begin of history list with a submit button.
Definition: HistoryAction.php:461
Html\rawElement
static rawElement( $element, $attribs=array(), $contents='')
Returns an HTML element in a string.
Definition: Html.php:124
Revision\selectFields
static selectFields()
Return the list of revision fields that should be selected to create a new revision.
Definition: Revision.php:405
$query
return true to allow those checks to and false if checking is done use this to change the tables headers temp or archived zone change it to an object instance and return false override the list derivative used the name of the old file when set the default code will be skipped add a value to it if you want to add a cookie that have to vary cache options can modify $query
Definition: hooks.txt:1105
$attribs
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return an< a > element with HTML attributes $attribs and contents $html will be returned If you return $ret will be returned and may include noclasses after processing & $attribs
Definition: hooks.txt:1530
HistoryAction\DIR_PREV
const DIR_PREV
Definition: HistoryAction.php:37
$article
Using a hook running we can avoid having all this option specific stuff in our mainline code Using the function array $article
Definition: hooks.txt:78
message
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return an< a > element with HTML attributes $attribs and contents $html will be returned If you return $ret will be returned and may include noclasses after processing after in associative array form externallinks including delete and has completed for all link tables default is conds Array Extra conditions for the No matching items in log is displayed if loglist is empty msgKey Array If you want a nice box with a message
Definition: hooks.txt:1624
HistoryAction\getArticle
getArticle()
Get the Article object we are working on.
Definition: HistoryAction.php:72
MWTimestamp\getLocalInstance
static getLocalInstance( $ts=false)
Get a timestamp instance in the server local timezone ($wgLocaltimezone)
Definition: MWTimestamp.php:373
ReverseChronologicalPager\getDateCond
getDateCond( $year, $month)
Definition: Pager.php:864
Revision\DELETED_TEXT
const DELETED_TEXT
Definition: Revision.php:65
IndexPager\getNumRows
getNumRows()
Get the number of rows in the result set.
Definition: Pager.php:550
Xml\fieldset
static fieldset( $legend=false, $content=false, $attribs=array())
Shortcut for creating fieldsets.
Definition: Xml.php:563
ChangeTags\formatSummaryRow
static formatSummaryRow( $tags, $page)
Creates HTML for the given tags.
Definition: ChangeTags.php:34
LogEventsList\showLogExtract
static showLogExtract(&$out, $types=array(), $page='', $user='', $param=array())
Show log extract.
Definition: LogEventsList.php:507
page
do that in ParserLimitReportFormat instead use this to modify the parameters of the image and a DIV can begin in one section and end in another Make sure your code can handle that case gracefully See the EditSectionClearerLink extension for an example zero but section is usually empty its values are the globals values my talk page
Definition: hooks.txt:1956
HistoryPager\lastLink
lastLink( $prevRev, $next)
Create a diff-to-previous link for this revision for this page.
Definition: HistoryAction.php:780
$type
$type
Definition: testCompression.php:46