mAttribs = $rc->mAttribs; $rc2->mExtra = $rc->mExtra; return $rc2; } } /** * Base class for all changes lists */ class ChangesList extends ContextSource { /** * @var Skin */ public $skin; protected $watchlist = false; protected $message; /** * Changeslist contructor * * @param $obj Skin or IContextSource */ public function __construct( $obj ) { if ( $obj instanceof IContextSource ) { $this->setContext( $obj ); $this->skin = $obj->getSkin(); } else { $this->setContext( $obj->getContext() ); $this->skin = $obj; } $this->preCacheMessages(); } /** * Fetch an appropriate changes list class for the main context * This first argument used to be an User object. * * @deprecated in 1.18; use newFromContext() instead * @param $unused string|User Unused * @return ChangesList|EnhancedChangesList|OldChangesList derivative */ public static function newFromUser( $unused ) { wfDeprecated( __METHOD__, '1.18' ); return self::newFromContext( RequestContext::getMain() ); } /** * Fetch an appropriate changes list class for the specified context * Some users might want to use an enhanced list format, for instance * * @param $context IContextSource to use * @return ChangesList|EnhancedChangesList|OldChangesList derivative */ public static function newFromContext( IContextSource $context ) { $user = $context->getUser(); $sk = $context->getSkin(); $list = null; if( wfRunHooks( 'FetchChangesList', array( $user, &$sk, &$list ) ) ) { $new = $context->getRequest()->getBool( 'enhanced', $user->getOption( 'usenewrc' ) ); return $new ? new EnhancedChangesList( $context ) : new OldChangesList( $context ); } else { return $list; } } /** * Sets the list to use a "
  • " tag * @param $value Boolean */ public function setWatchlistDivs( $value = true ) { $this->watchlist = $value; } /** * As we use the same small set of messages in various methods and that * they are called often, we call them once and save them in $this->message */ private function preCacheMessages() { if( !isset( $this->message ) ) { foreach ( explode( ' ', 'cur diff hist last blocklink history ' . 'semicolon-separator pipe-separator' ) as $msg ) { $this->message[$msg] = $this->msg( $msg )->escaped(); } } } /** * Returns the appropriate flags for new page, minor change and patrolling * @param $flags Array Associative array of 'flag' => Bool * @param $nothing String to use for empty space * @return String */ protected function recentChangesFlags( $flags, $nothing = ' ' ) { $f = ''; foreach( array( 'newpage', 'minor', 'bot', 'unpatrolled' ) as $flag ){ $f .= isset( $flags[$flag] ) && $flags[$flag] ? self::flag( $flag ) : $nothing; } return $f; } /** * Provide the "" element appropriate to a given abbreviated flag, * namely the flag indicating a new page, a minor edit, a bot edit, or an * unpatrolled edit. By default in English it will contain "N", "m", "b", * "!" respectively, plus it will have an appropriate title and class. * * @param $flag String: 'newpage', 'unpatrolled', 'minor', or 'bot' * @return String: Raw HTML */ public static function flag( $flag ) { static $messages = null; if ( is_null( $messages ) ) { $messages = array( 'newpage' => array( 'newpageletter', 'recentchanges-label-newpage' ), 'minoredit' => array( 'minoreditletter', 'recentchanges-label-minor' ), 'botedit' => array( 'boteditletter', 'recentchanges-label-bot' ), 'unpatrolled' => array( 'unpatrolledletter', 'recentchanges-label-unpatrolled' ), ); foreach( $messages as &$value ) { $value[0] = wfMessage( $value[0] )->escaped(); $value[1] = wfMessage( $value[1] )->escaped(); } } # Inconsistent naming, bleh $map = array( 'newpage' => 'newpage', 'minor' => 'minoredit', 'bot' => 'botedit', 'unpatrolled' => 'unpatrolled', 'minoredit' => 'minoredit', 'botedit' => 'botedit', ); $flag = $map[$flag]; return "" . $messages[$flag][0] . ''; } /** * Returns text for the start of the tabular part of RC * @return String */ public function beginRecentChangesList() { $this->rc_cache = array(); $this->rcMoveIndex = 0; $this->rcCacheIndex = 0; $this->lastdate = ''; $this->rclistOpen = false; $this->getOutput()->addModuleStyles( 'mediawiki.special.changeslist' ); return ''; } /** * Show formatted char difference * @param $old Integer: bytes * @param $new Integer: bytes * @param $context IContextSource context to use * @return String */ public static function showCharacterDifference( $old, $new, IContextSource $context = null ) { global $wgRCChangedSizeThreshold, $wgMiserMode; if ( !$context ) { $context = RequestContext::getMain(); } $new = (int)$new; $old = (int)$old; $szdiff = $new - $old; $lang = $context->getLanguage(); $code = $lang->getCode(); static $fastCharDiff = array(); if ( !isset($fastCharDiff[$code]) ) { $fastCharDiff[$code] = $wgMiserMode || $context->msg( 'rc-change-size' )->plain() === '$1'; } $formattedSize = $lang->formatNum( $szdiff ); if ( !$fastCharDiff[$code] ) { $formattedSize = $context->msg( 'rc-change-size', $formattedSize )->text(); } if( abs( $szdiff ) > abs( $wgRCChangedSizeThreshold ) ) { $tag = 'strong'; } else { $tag = 'span'; } if ( $szdiff === 0 ) { $formattedSizeClass = 'mw-plusminus-null'; } if ( $szdiff > 0 ) { $formattedSize = '+' . $formattedSize; $formattedSizeClass = 'mw-plusminus-pos'; } if ( $szdiff < 0 ) { $formattedSizeClass = 'mw-plusminus-neg'; } $formattedTotalSize = $context->msg( 'rc-change-size-new' )->numParams( $new )->text(); return Html::element( $tag, array( 'dir' => 'ltr', 'class' => $formattedSizeClass, 'title' => $formattedTotalSize ), $context->msg( 'parentheses', $formattedSize )->plain() ) . $lang->getDirMark(); } /** * Format the character difference of one or several changes. * * @param $old RecentChange * @param $new RecentChange last change to use, if not provided, $old will be used * @return string HTML fragment */ public function formatCharacterDifference( RecentChange $old, RecentChange $new = null ) { $oldlen = $old->mAttribs['rc_old_len']; if ( $new ) { $newlen = $new->mAttribs['rc_new_len']; } else { $newlen = $old->mAttribs['rc_new_len']; } if( $oldlen === null || $newlen === null ) { return ''; } return self::showCharacterDifference( $oldlen, $newlen, $this->getContext() ); } /** * Returns text for the end of RC * @return String */ public function endRecentChangesList() { if( $this->rclistOpen ) { return "\n"; } else { return ''; } } public function insertDateHeader( &$s, $rc_timestamp ) { # Make date header if necessary $date = $this->getLanguage()->userDate( $rc_timestamp, $this->getUser() ); if( $date != $this->lastdate ) { if( $this->lastdate != '' ) { $s .= "\n"; } $s .= Xml::element( 'h4', null, $date ) . "\n