MediaWiki  master
ChangesList.php
Go to the documentation of this file.
1 <?php
28 
29 class ChangesList extends ContextSource {
30  const CSS_CLASS_PREFIX = 'mw-changeslist-';
31 
35  public $skin;
36 
37  protected $watchlist = false;
38  protected $lastdate;
39  protected $message;
40  protected $rc_cache;
41  protected $rcCacheIndex;
42  protected $rclistOpen;
43  protected $rcMoveIndex;
44 
47 
49  protected $watchMsgCache;
50 
54  protected $linkRenderer;
55 
59  protected $filterGroups;
60 
65  public function __construct( $obj, array $filterGroups = [] ) {
66  if ( $obj instanceof IContextSource ) {
67  $this->setContext( $obj );
68  $this->skin = $obj->getSkin();
69  } else {
70  $this->setContext( $obj->getContext() );
71  $this->skin = $obj;
72  }
73  $this->preCacheMessages();
74  $this->watchMsgCache = new MapCacheLRU( 50 );
75  $this->linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
76  $this->filterGroups = $filterGroups;
77  }
78 
87  public static function newFromContext( IContextSource $context, array $groups = [] ) {
88  $user = $context->getUser();
89  $sk = $context->getSkin();
90  $list = null;
91  if ( Hooks::run( 'FetchChangesList', [ $user, &$sk, &$list, $groups ] ) ) {
92  $new = $context->getRequest()->getBool( 'enhanced', $user->getOption( 'usenewrc' ) );
93 
94  return $new ?
95  new EnhancedChangesList( $context, $groups ) :
96  new OldChangesList( $context, $groups );
97  } else {
98  return $list;
99  }
100  }
101 
113  public function recentChangesLine( &$rc, $watched = false, $linenumber = null ) {
114  throw new RuntimeException( 'recentChangesLine should be implemented' );
115  }
116 
123  protected function getHighlightsContainerDiv() {
124  $highlightColorDivs = '';
125  foreach ( [ 'none', 'c1', 'c2', 'c3', 'c4', 'c5' ] as $color ) {
126  $highlightColorDivs .= Html::rawElement(
127  'div',
128  [
129  'class' => 'mw-rcfilters-ui-highlights-color-' . $color,
130  'data-color' => $color
131  ]
132  );
133  }
134 
135  return Html::rawElement(
136  'div',
137  [ 'class' => 'mw-rcfilters-ui-highlights' ],
138  $highlightColorDivs
139  );
140  }
141 
146  public function setWatchlistDivs( $value = true ) {
147  $this->watchlist = $value;
148  }
149 
154  public function isWatchlist() {
155  return (bool)$this->watchlist;
156  }
157 
162  private function preCacheMessages() {
163  if ( !isset( $this->message ) ) {
164  $this->message = [];
165  foreach ( [
166  'cur', 'diff', 'hist', 'enhancedrc-history', 'last', 'blocklink', 'history',
167  'semicolon-separator', 'pipe-separator' ] as $msg
168  ) {
169  $this->message[$msg] = $this->msg( $msg )->escaped();
170  }
171  }
172  }
173 
180  public function recentChangesFlags( $flags, $nothing = "\u{00A0}" ) {
181  $f = '';
182  foreach ( array_keys( $this->getConfig()->get( 'RecentChangesFlags' ) ) as $flag ) {
183  $f .= isset( $flags[$flag] ) && $flags[$flag]
184  ? self::flag( $flag, $this->getContext() )
185  : $nothing;
186  }
187 
188  return $f;
189  }
190 
199  protected function getHTMLClasses( $rc, $watched ) {
200  $classes = [ self::CSS_CLASS_PREFIX . 'line' ];
201  $logType = $rc->mAttribs['rc_log_type'];
202 
203  if ( $logType ) {
204  $classes[] = self::CSS_CLASS_PREFIX . 'log';
205  $classes[] = Sanitizer::escapeClass( self::CSS_CLASS_PREFIX . 'log-' . $logType );
206  } else {
207  $classes[] = self::CSS_CLASS_PREFIX . 'edit';
208  $classes[] = Sanitizer::escapeClass( self::CSS_CLASS_PREFIX . 'ns' .
209  $rc->mAttribs['rc_namespace'] . '-' . $rc->mAttribs['rc_title'] );
210  }
211 
212  // Indicate watched status on the line to allow for more
213  // comprehensive styling.
214  $classes[] = $watched && $rc->mAttribs['rc_timestamp'] >= $watched
215  ? self::CSS_CLASS_PREFIX . 'line-watched'
216  : self::CSS_CLASS_PREFIX . 'line-not-watched';
217 
218  $classes = array_merge( $classes, $this->getHTMLClassesForFilters( $rc ) );
219 
220  return $classes;
221  }
222 
230  protected function getHTMLClassesForFilters( $rc ) {
231  $classes = [];
232 
233  $classes[] = Sanitizer::escapeClass( self::CSS_CLASS_PREFIX . 'ns-' .
234  $rc->mAttribs['rc_namespace'] );
235 
236  $nsInfo = MediaWikiServices::getInstance()->getNamespaceInfo();
237  $classes[] = Sanitizer::escapeClass(
238  self::CSS_CLASS_PREFIX .
239  'ns-' .
240  ( $nsInfo->isTalk( $rc->mAttribs['rc_namespace'] ) ? 'talk' : 'subject' )
241  );
242 
243  if ( $this->filterGroups !== null ) {
244  foreach ( $this->filterGroups as $filterGroup ) {
245  foreach ( $filterGroup->getFilters() as $filter ) {
246  $filter->applyCssClassIfNeeded( $this, $rc, $classes );
247  }
248  }
249  }
250 
251  return $classes;
252  }
253 
262  public static function flag( $flag, IContextSource $context = null ) {
263  static $map = [ 'minoredit' => 'minor', 'botedit' => 'bot' ];
264  static $flagInfos = null;
265 
266  if ( is_null( $flagInfos ) ) {
267  global $wgRecentChangesFlags;
268  $flagInfos = [];
269  foreach ( $wgRecentChangesFlags as $key => $value ) {
270  $flagInfos[$key]['letter'] = $value['letter'];
271  $flagInfos[$key]['title'] = $value['title'];
272  // Allow customized class name, fall back to flag name
273  $flagInfos[$key]['class'] = $value['class'] ?? $key;
274  }
275  }
276 
278 
279  // Inconsistent naming, kepted for b/c
280  if ( isset( $map[$flag] ) ) {
281  $flag = $map[$flag];
282  }
283 
284  $info = $flagInfos[$flag];
285  return Html::element( 'abbr', [
286  'class' => $info['class'],
287  'title' => wfMessage( $info['title'] )->setContext( $context )->text(),
288  ], wfMessage( $info['letter'] )->setContext( $context )->text() );
289  }
290 
295  public function beginRecentChangesList() {
296  $this->rc_cache = [];
297  $this->rcMoveIndex = 0;
298  $this->rcCacheIndex = 0;
299  $this->lastdate = '';
300  $this->rclistOpen = false;
301  $this->getOutput()->addModuleStyles( [
302  'mediawiki.interface.helpers.styles',
303  'mediawiki.special.changeslist'
304  ] );
305 
306  return '<div class="mw-changeslist">';
307  }
308 
312  public function initChangesListRows( $rows ) {
313  Hooks::run( 'ChangesListInitRows', [ $this, $rows ] );
314  }
315 
326  public static function showCharacterDifference( $old, $new, IContextSource $context = null ) {
327  if ( !$context ) {
329  }
330 
331  $new = (int)$new;
332  $old = (int)$old;
333  $szdiff = $new - $old;
334 
336  $config = $context->getConfig();
337  $code = $lang->getCode();
338  static $fastCharDiff = [];
339  if ( !isset( $fastCharDiff[$code] ) ) {
340  $fastCharDiff[$code] = $config->get( 'MiserMode' )
341  || $context->msg( 'rc-change-size' )->plain() === '$1';
342  }
343 
344  $formattedSize = $lang->formatNum( $szdiff );
345 
346  if ( !$fastCharDiff[$code] ) {
347  $formattedSize = $context->msg( 'rc-change-size', $formattedSize )->text();
348  }
349 
350  if ( abs( $szdiff ) > abs( $config->get( 'RCChangedSizeThreshold' ) ) ) {
351  $tag = 'strong';
352  } else {
353  $tag = 'span';
354  }
355 
356  if ( $szdiff === 0 ) {
357  $formattedSizeClass = 'mw-plusminus-null';
358  } elseif ( $szdiff > 0 ) {
359  $formattedSize = '+' . $formattedSize;
360  $formattedSizeClass = 'mw-plusminus-pos';
361  } else {
362  $formattedSizeClass = 'mw-plusminus-neg';
363  }
364  $formattedSizeClass .= ' mw-diff-bytes';
365 
366  $formattedTotalSize = $context->msg( 'rc-change-size-new' )->numParams( $new )->text();
367 
368  return Html::element( $tag,
369  [ 'dir' => 'ltr', 'class' => $formattedSizeClass, 'title' => $formattedTotalSize ],
370  $formattedSize ) . $lang->getDirMark();
371  }
372 
380  public function formatCharacterDifference( RecentChange $old, RecentChange $new = null ) {
381  $oldlen = $old->mAttribs['rc_old_len'];
382 
383  if ( $new ) {
384  $newlen = $new->mAttribs['rc_new_len'];
385  } else {
386  $newlen = $old->mAttribs['rc_new_len'];
387  }
388 
389  if ( $oldlen === null || $newlen === null ) {
390  return '';
391  }
392 
393  return self::showCharacterDifference( $oldlen, $newlen, $this->getContext() );
394  }
395 
400  public function endRecentChangesList() {
401  $out = $this->rclistOpen ? "</ul>\n" : '';
402  $out .= '</div>';
403 
404  return $out;
405  }
406 
418  public static function revDateLink( Revision $rev, User $user, Language $lang, $title = null ) {
419  $ts = $rev->getTimestamp();
420  $date = $lang->userTimeAndDate( $ts, $user );
421  if ( $rev->userCan( RevisionRecord::DELETED_TEXT, $user ) ) {
422  $link = MediaWikiServices::getInstance()->getLinkRenderer()->makeKnownLink(
423  $title ?? $rev->getTitle(),
424  $date,
425  [ 'class' => 'mw-changeslist-date' ],
426  [ 'oldid' => $rev->getId() ]
427  );
428  } else {
429  $link = htmlspecialchars( $date );
430  }
431  if ( $rev->isDeleted( RevisionRecord::DELETED_TEXT ) ) {
432  $link = "<span class=\"history-deleted mw-changeslist-date\">$link</span>";
433  }
434  return $link;
435  }
436 
441  public function insertDateHeader( &$s, $rc_timestamp ) {
442  # Make date header if necessary
443  $date = $this->getLanguage()->userDate( $rc_timestamp, $this->getUser() );
444  if ( $date != $this->lastdate ) {
445  if ( $this->lastdate != '' ) {
446  $s .= "</ul>\n";
447  }
448  $s .= Xml::element( 'h4', null, $date ) . "\n<ul class=\"special\">";
449  $this->lastdate = $date;
450  $this->rclistOpen = true;
451  }
452  }
453 
460  public function insertLog( &$s, $title, $logtype, $useParentheses = true ) {
461  $page = new LogPage( $logtype );
462  $logname = $page->getName()->setContext( $this->getContext() )->text();
463  $link = $this->linkRenderer->makeKnownLink( $title, $logname, [
464  'class' => $useParentheses ? '' : 'mw-changeslist-links'
465  ] );
466  if ( $useParentheses ) {
467  $s .= $this->msg( 'parentheses' )->rawParams(
468  $link
469  )->escaped();
470  } else {
471  $s .= $link;
472  }
473  }
474 
480  public function insertDiffHist( &$s, &$rc, $unpatrolled = null ) {
481  # Diff link
482  if (
483  $rc->mAttribs['rc_type'] == RC_NEW ||
484  $rc->mAttribs['rc_type'] == RC_LOG ||
485  $rc->mAttribs['rc_type'] == RC_CATEGORIZE
486  ) {
487  $diffLink = $this->message['diff'];
488  } elseif ( !self::userCan( $rc, RevisionRecord::DELETED_TEXT, $this->getUser() ) ) {
489  $diffLink = $this->message['diff'];
490  } else {
491  $query = [
492  'curid' => $rc->mAttribs['rc_cur_id'],
493  'diff' => $rc->mAttribs['rc_this_oldid'],
494  'oldid' => $rc->mAttribs['rc_last_oldid']
495  ];
496 
497  $diffLink = $this->linkRenderer->makeKnownLink(
498  $rc->getTitle(),
499  new HtmlArmor( $this->message['diff'] ),
500  [ 'class' => 'mw-changeslist-diff' ],
501  $query
502  );
503  }
504  if ( $rc->mAttribs['rc_type'] == RC_CATEGORIZE ) {
505  $histLink = $this->message['hist'];
506  } else {
507  $histLink = $this->linkRenderer->makeKnownLink(
508  $rc->getTitle(),
509  new HtmlArmor( $this->message['hist'] ),
510  [ 'class' => 'mw-changeslist-history' ],
511  [
512  'curid' => $rc->mAttribs['rc_cur_id'],
513  'action' => 'history'
514  ]
515  );
516  }
517 
518  $s .= Html::rawElement( 'div', [ 'class' => 'mw-changeslist-links' ],
519  Html::rawElement( 'span', [], $diffLink ) .
520  Html::rawElement( 'span', [], $histLink )
521  ) .
522  ' <span class="mw-changeslist-separator"></span> ';
523  }
524 
532  public function getArticleLink( &$rc, $unpatrolled, $watched ) {
533  $params = [];
534  if ( $rc->getTitle()->isRedirect() ) {
535  $params = [ 'redirect' => 'no' ];
536  }
537 
538  $articlelink = $this->linkRenderer->makeLink(
539  $rc->getTitle(),
540  null,
541  [ 'class' => 'mw-changeslist-title' ],
542  $params
543  );
544  if ( $this->isDeleted( $rc, RevisionRecord::DELETED_TEXT ) ) {
545  $articlelink = '<span class="history-deleted">' . $articlelink . '</span>';
546  }
547  # To allow for boldening pages watched by this user
548  $articlelink = "<span class=\"mw-title\">{$articlelink}</span>";
549  # RTL/LTR marker
550  $articlelink .= $this->getLanguage()->getDirMark();
551 
552  # TODO: Deprecate the $s argument, it seems happily unused.
553  $s = '';
554  # Avoid PHP 7.1 warning from passing $this by reference
555  $changesList = $this;
556  Hooks::run( 'ChangesListInsertArticleLink',
557  [ &$changesList, &$articlelink, &$s, &$rc, $unpatrolled, $watched ] );
558 
559  return "{$s} {$articlelink}";
560  }
561 
570  public function getTimestamp( $rc ) {
571  // A space is important after mw-changeslist-separator--semicolon to make sure
572  // that whatever comes before it is distinguishable.
573  // (Otherwise your have the text of titles pushing up against the timestamp)
574  // A specific element is used for this purpose as `mw-changeslist-date` is used in a variety
575  // of other places with a different position and the information proceeding getTimestamp can vary.
576  return '<span class="mw-changeslist-separator--semicolon"></span> ' .
577  '<span class="mw-changeslist-date">' .
578  htmlspecialchars( $this->getLanguage()->userTime(
579  $rc->mAttribs['rc_timestamp'],
580  $this->getUser()
581  ) ) . '</span> <span class="mw-changeslist-separator"></span> ';
582  }
583 
590  public function insertTimestamp( &$s, $rc ) {
591  $s .= $this->getTimestamp( $rc );
592  }
593 
600  public function insertUserRelatedLinks( &$s, &$rc ) {
601  if ( $this->isDeleted( $rc, RevisionRecord::DELETED_USER ) ) {
602  $s .= ' <span class="history-deleted">' .
603  $this->msg( 'rev-deleted-user' )->escaped() . '</span>';
604  } else {
605  $s .= $this->getLanguage()->getDirMark() . Linker::userLink( $rc->mAttribs['rc_user'],
606  $rc->mAttribs['rc_user_text'] );
608  $rc->mAttribs['rc_user'], $rc->mAttribs['rc_user_text'],
609  false, 0, null,
610  // The text content of tools is not wrapped with parenthesises or "piped".
611  // This will be handled in CSS (T205581).
612  false
613  );
614  }
615  }
616 
623  public function insertLogEntry( $rc ) {
624  $formatter = LogFormatter::newFromRow( $rc->mAttribs );
625  $formatter->setContext( $this->getContext() );
626  $formatter->setShowUserToolLinks( true );
627  $mark = $this->getLanguage()->getDirMark();
628 
629  return Html::openElement( 'span', [ 'class' => 'mw-changeslist-log-entry' ] )
630  . $formatter->getActionText() . " $mark" . $formatter->getComment()
631  . Html::closeElement( 'span' );
632  }
633 
639  public function insertComment( $rc ) {
640  if ( $this->isDeleted( $rc, RevisionRecord::DELETED_COMMENT ) ) {
641  return ' <span class="history-deleted comment">' .
642  $this->msg( 'rev-deleted-comment' )->escaped() . '</span>';
643  } else {
644  return Linker::commentBlock( $rc->mAttribs['rc_comment'], $rc->getTitle(),
645  // Whether section links should refer to local page (using default false)
646  false,
647  // wikid to generate links for (using default null) */
648  null,
649  // whether parentheses should be rendered as part of the message
650  false );
651  }
652  }
653 
659  protected function numberofWatchingusers( $count ) {
660  if ( $count <= 0 ) {
661  return '';
662  }
663 
664  return $this->watchMsgCache->getWithSetCallback(
665  "watching-users-msg:$count",
666  function () use ( $count ) {
667  return $this->msg( 'number-of-watching-users-for-recent-changes' )
668  ->numParams( $count )->escaped();
669  }
670  );
671  }
672 
679  public static function isDeleted( $rc, $field ) {
680  return ( $rc->mAttribs['rc_deleted'] & $field ) == $field;
681  }
682 
692  public static function userCan( $rc, $field, User $user = null ) {
693  if ( $user === null ) {
694  $user = RequestContext::getMain()->getUser();
695  }
696 
697  if ( $rc->mAttribs['rc_type'] == RC_LOG ) {
698  return LogEventsList::userCanBitfield( $rc->mAttribs['rc_deleted'], $field, $user );
699  }
700 
701  return RevisionRecord::userCanBitfield( $rc->mAttribs['rc_deleted'], $field, $user );
702  }
703 
709  protected function maybeWatchedLink( $link, $watched = false ) {
710  if ( $watched ) {
711  return '<strong class="mw-watched">' . $link . '</strong>';
712  } else {
713  return '<span class="mw-rc-unwatched">' . $link . '</span>';
714  }
715  }
716 
723  public function insertRollback( &$s, &$rc ) {
724  if ( $rc->mAttribs['rc_type'] == RC_EDIT
725  && $rc->mAttribs['rc_this_oldid']
726  && $rc->mAttribs['rc_cur_id']
727  && $rc->getAttribute( 'page_latest' ) == $rc->mAttribs['rc_this_oldid']
728  ) {
729  $title = $rc->getTitle();
733  if ( MediaWikiServices::getInstance()->getPermissionManager()
734  ->quickUserCan( 'rollback', $this->getUser(), $title )
735  ) {
736  $rev = new Revision( [
737  'title' => $title,
738  'id' => $rc->mAttribs['rc_this_oldid'],
739  'user' => $rc->mAttribs['rc_user'],
740  'user_text' => $rc->mAttribs['rc_user_text'],
741  'actor' => $rc->mAttribs['rc_actor'] ?? null,
742  'deleted' => $rc->mAttribs['rc_deleted']
743  ] );
744  $s .= ' ' . Linker::generateRollback( $rev, $this->getContext(),
745  [ 'noBrackets' ] );
746  }
747  }
748  }
749 
755  public function getRollback( RecentChange $rc ) {
756  $s = '';
757  $this->insertRollback( $s, $rc );
758  return $s;
759  }
760 
766  public function insertTags( &$s, &$rc, &$classes ) {
767  if ( empty( $rc->mAttribs['ts_tags'] ) ) {
768  return;
769  }
770 
771  list( $tagSummary, $newClasses ) = ChangeTags::formatSummaryRow(
772  $rc->mAttribs['ts_tags'],
773  'changeslist',
774  $this->getContext()
775  );
776  $classes = array_merge( $classes, $newClasses );
777  $s .= ' ' . $tagSummary;
778  }
779 
786  public function getTags( RecentChange $rc, array &$classes ) {
787  $s = '';
788  $this->insertTags( $s, $rc, $classes );
789  return $s;
790  }
791 
792  public function insertExtra( &$s, &$rc, &$classes ) {
793  // Empty, used for subclasses to add anything special.
794  }
795 
796  protected function showAsUnpatrolled( RecentChange $rc ) {
797  return self::isUnpatrolled( $rc, $this->getUser() );
798  }
799 
805  public static function isUnpatrolled( $rc, User $user ) {
806  if ( $rc instanceof RecentChange ) {
807  $isPatrolled = $rc->mAttribs['rc_patrolled'];
808  $rcType = $rc->mAttribs['rc_type'];
809  $rcLogType = $rc->mAttribs['rc_log_type'];
810  } else {
811  $isPatrolled = $rc->rc_patrolled;
812  $rcType = $rc->rc_type;
813  $rcLogType = $rc->rc_log_type;
814  }
815 
816  if ( !$isPatrolled ) {
817  if ( $user->useRCPatrol() ) {
818  return true;
819  }
820  if ( $user->useNPPatrol() && $rcType == RC_NEW ) {
821  return true;
822  }
823  if ( $user->useFilePatrol() && $rcLogType == 'upload' ) {
824  return true;
825  }
826  }
827 
828  return false;
829  }
830 
840  protected function isCategorizationWithoutRevision( $rcObj ) {
841  return intval( $rcObj->getAttribute( 'rc_type' ) ) === RC_CATEGORIZE
842  && intval( $rcObj->getAttribute( 'rc_this_oldid' ) ) === 0;
843  }
844 
850  protected function getDataAttributes( RecentChange $rc ) {
851  $attrs = [];
852 
853  $type = $rc->getAttribute( 'rc_source' );
854  switch ( $type ) {
857  $attrs['data-mw-revid'] = $rc->mAttribs['rc_this_oldid'];
858  break;
860  $attrs['data-mw-logid'] = $rc->mAttribs['rc_logid'];
861  $attrs['data-mw-logaction'] =
862  $rc->mAttribs['rc_log_type'] . '/' . $rc->mAttribs['rc_log_action'];
863  break;
864  }
865 
866  $attrs[ 'data-mw-ts' ] = $rc->getAttribute( 'rc_timestamp' );
867 
868  return $attrs;
869  }
870 
878  public function setChangeLinePrefixer( callable $prefixer ) {
879  $this->changeLinePrefixer = $prefixer;
880  }
881 }
getHTMLClassesForFilters( $rc)
Get an array of CSS classes attributed to filters for this row.
setContext(IContextSource $context)
userCan( $field, User $user=null)
Determine if the current user is allowed to view a particular field of this revision, if it&#39;s marked as deleted.
Definition: Revision.php:1023
setWatchlistDivs( $value=true)
Sets the list to use a "<li class=&#39;watchlist-(namespace)-(page)&#39;>" tag.
const RC_CATEGORIZE
Definition: Defines.php:126
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:231
endRecentChangesList()
Returns text for the end of RC.
MapCacheLRU $watchMsgCache
Definition: ChangesList.php:49
insertExtra(&$s, &$rc, &$classes)
insertRollback(&$s, &$rc)
Insert a rollback link.
getTimestamp()
Definition: Revision.php:799
$wgRecentChangesFlags
Flags (letter symbols) shown in recent changes and watchlist to indicate certain types of edits...
The simplest way of implementing IContextSource is to hold a RequestContext as a member variable and ...
userTimeAndDate( $ts, User $user, array $options=[])
Get the formatted date and time for the given timestamp and formatted for the given user...
Definition: Language.php:2456
if(!isset( $args[0])) $lang
getTags(RecentChange $rc, array &$classes)
static openElement( $element, $attribs=[])
Identical to rawElement(), but has no third parameter and omits the end tag (and the self-closing &#39;/&#39;...
Definition: Html.php:251
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Definition: Html.php:209
getAttribute( $name)
Get an attribute value.
insertLog(&$s, $title, $logtype, $useParentheses=true)
recentChangesFlags( $flags, $nothing="\00A0}")
Returns the appropriate flags for new page, minor change and patrolling.
setChangeLinePrefixer(callable $prefixer)
Sets the callable that generates a change line prefix added to the beginning of each line...
formatCharacterDifference(RecentChange $old, RecentChange $new=null)
Format the character difference of one or several changes.
static generateRollback( $rev, IContextSource $context=null, $options=[ 'verify'])
Generate a rollback link for a given revision.
Definition: Linker.php:1807
IContextSource $context
insertDateHeader(&$s, $rc_timestamp)
array $filterGroups
Definition: ChangesList.php:59
maybeWatchedLink( $link, $watched=false)
Class to simplify the use of log pages.
Definition: LogPage.php:33
const CSS_CLASS_PREFIX
Definition: ChangesList.php:30
The User object encapsulates all of the user-specific settings (user_id, name, rights, email address, options, last login time).
Definition: User.php:51
getPermissionManager()
getHighlightsContainerDiv()
Get the container for highlights that are used in the new StructuredFilters system.
getConfig()
Get the site configuration.
insertUserRelatedLinks(&$s, &$rc)
Insert links to user page, user talk page and eventually a blocking link.
getTitle()
Returns the title of the page associated with this entry.
Definition: Revision.php:560
static getMain()
Get the RequestContext object associated with the main request.
getDataAttributes(RecentChange $rc)
Get recommended data attributes for a change line.
static flag( $flag, IContextSource $context=null)
Make an "<abbr>" element for a given change flag.
isDeleted( $field)
Definition: Revision.php:693
getId()
Get revision ID.
Definition: Revision.php:443
msg( $key,... $params)
This is the method for getting translated interface messages.
static isDeleted( $rc, $field)
Determine if said field of a revision is hidden.
static userToolLinks( $userId, $userText, $redContribsWhenNoEdits=false, $flags=0, $edits=null, $useParentheses=true)
Generate standard user tool links (talk, contributions, block link, etc.)
Definition: Linker.php:943
insertLogEntry( $rc)
Insert a formatted action.
static userCanBitfield( $bitfield, $field, User $user=null)
Determine if the current user is allowed to view a particular field of this log row, if it&#39;s marked as deleted.
getRollback(RecentChange $rc)
getArticleLink(&$rc, $unpatrolled, $watched)
showAsUnpatrolled(RecentChange $rc)
getContext()
Get the base IContextSource object.
static revDateLink(Revision $rev, User $user, Language $lang, $title=null)
Render the date and time of a revision in the current user language based on whether the user is able...
static closeElement( $element)
Returns "</$element>".
Definition: Html.php:315
static escapeClass( $class)
Given a value, escape it so that it can be used as a CSS class and return it.
Definition: Sanitizer.php:1380
getHTMLClasses( $rc, $watched)
Get an array of default HTML class attributes for the change.
static newFromRow( $row)
Handy shortcut for constructing a formatter directly from database row.
insertTimestamp(&$s, $rc)
Insert time timestamp string from $rc into $s.
static showCharacterDifference( $old, $new, IContextSource $context=null)
Show formatted char difference.
insertTags(&$s, &$rc, &$classes)
useRCPatrol()
Check whether to enable recent changes patrol features for this user.
Definition: User.php:3668
static newFromContext(IContextSource $context, array $groups=[])
Fetch an appropriate changes list class for the specified context Some users might want to use an enh...
Definition: ChangesList.php:87
static userLink( $userId, $userName, $altUserName=false)
Make user link (or user contributions for unregistered users)
Definition: Linker.php:898
preCacheMessages()
As we use the same small set of messages in various methods and that they are called often...
beginRecentChangesList()
Returns text for the start of the tabular part of RC.
static isUnpatrolled( $rc, User $user)
useFilePatrol()
Check whether to enable new files patrol features for this user.
Definition: User.php:3689
callable $changeLinePrefixer
Definition: ChangesList.php:46
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
__construct( $obj, array $filterGroups=[])
Definition: ChangesList.php:65
static element( $element, $attribs=null, $contents='', $allowShortTag=true)
Format an XML element with given attributes and, optionally, text content.
Definition: Xml.php:41
useNPPatrol()
Check whether to enable new pages patrol features for this user.
Definition: User.php:3677
static userCan( $rc, $field, User $user=null)
Determine if the current user is allowed to view a particular field of this revision, if it&#39;s marked as deleted.
numberofWatchingusers( $count)
Returns the string which indicates the number of watching users.
LinkRenderer $linkRenderer
Definition: ChangesList.php:54
static formatSummaryRow( $tags, $page, IContextSource $context=null)
Creates HTML for the given tags.
Definition: ChangeTags.php:99
initChangesListRows( $rows)
const RC_NEW
Definition: Defines.php:123
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
insertComment( $rc)
Insert a formatted comment.
recentChangesLine(&$rc, $watched=false, $linenumber=null)
Format a line.
insertDiffHist(&$s, &$rc, $unpatrolled=null)
static commentBlock( $comment, $title=null, $local=false, $wikiId=null, $useParentheses=true)
Wrap a comment in standard punctuation and formatting if it&#39;s non-empty, otherwise return empty strin...
Definition: Linker.php:1543
isCategorizationWithoutRevision( $rcObj)
Determines whether a revision is linked to this change; this may not be the case when the categorizat...
const RC_EDIT
Definition: Defines.php:122
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:200
const RC_LOG
Definition: Defines.php:124
getTimestamp( $rc)
Get the timestamp from $rc formatted with current user&#39;s settings and a separator.