X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FChangesList.php;h=8b8fd50f0c3e65526c729adb369cec0ddd4d9dc8;hb=a35b7d2a5e5e695d54ef6cacd9194a35e502c048;hp=fe3ec1b32d830495082f7b007e45de70b9b2ee57;hpb=a3b490d2c4dfc25d7e0594eae8ee27ba69f6afea;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/ChangesList.php b/includes/ChangesList.php index fe3ec1b32d..8b8fd50f0c 100644 --- a/includes/ChangesList.php +++ b/includes/ChangesList.php @@ -1,15 +1,7 @@ mAttribs = $rc->mAttribs; $rc2->mExtra = $rc->mExtra; @@ -27,14 +18,20 @@ class RCCacheEntry extends RecentChange } ; /** - * @package MediaWiki + * Class to show various lists of changes: + * - what links here + * - related changes + * - recent changes */ class ChangesList { # Called by history lists and recent changes # - /** @todo document */ - function ChangesList( &$skin ) { + /** + * Changeslist contructor + * @param Skin $skin + */ + function __construct( &$skin ) { $this->skin =& $skin; $this->preCacheMessages(); } @@ -46,10 +43,10 @@ class ChangesList { * @param $user User to fetch the list class for * @return ChangesList derivative */ - function newFromUser( &$user ) { - $sk =& $user->getSkin(); + public static function newFromUser( &$user ) { + $sk = $user->getSkin(); $list = NULL; - if( wfRunHooks( 'FetchChangesList', array( &$user, &$skin, &$list ) ) ) { + if( wfRunHooks( 'FetchChangesList', array( &$user, &$sk, &$list ) ) ) { return $user->getOption( 'usenewrc' ) ? new EnhancedChangesList( $sk ) : new OldChangesList( $sk ); } else { return $list; @@ -60,12 +57,12 @@ class ChangesList { * 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 */ - function preCacheMessages() { + private function preCacheMessages() { // Precache various messages if( !isset( $this->message ) ) { foreach( explode(' ', 'cur diff hist minoreditletter newpageletter last '. - 'blocklink changes history boteditletter' ) as $msg ) { - $this->message[$msg] = wfMsgExt( $msg, array( 'escape') ); + 'blocklink history boteditletter semicolon-separator' ) as $msg ) { + $this->message[$msg] = wfMsgExt( $msg, array( 'escapenoentities' ) ); } } } @@ -73,21 +70,49 @@ class ChangesList { /** * Returns the appropriate flags for new page, minor change and patrolling + * @param bool $new + * @param bool $minor + * @param bool $patrolled + * @param string $nothing, string to use for empty space + * @param bool $bot + * @param bool $newbie + * @return string */ - function recentChangesFlags( $new, $minor, $patrolled, $nothing = ' ', $bot = false ) { + protected function recentChangesFlags( $new, $minor, $patrolled, $nothing = ' ', $bot = false, $newbie = false ) { $f = $new ? '' . $this->message['newpageletter'] . '' : $nothing; $f .= $minor ? '' . $this->message['minoreditletter'] . '' : $nothing; $f .= $bot ? '' . $this->message['boteditletter'] . '' : $nothing; $f .= $patrolled ? '!' : $nothing; + $f .= $newbie ? '*' : $nothing; return $f; } + + protected static function userIsNew( $attribs ) { + global $wgAutoConfirmCount, $wgAutoConfirmAge; + if( !array_key_exists('user_editcount',$attribs) || !array_key_exists('user_registration',$attribs) ) { + return false; // missing input! + } + static $time; + $time = time(); + $edits = $attribs['user_editcount']; + $age = $attribs['user_registration']; + if( $wgAutoConfirmCount && !$edits || $wgAutoConfirmAge && !$age ) { + return true; + } else if( $wgAutoConfirmCount && $edits < $wgAutoConfirmCount ) { + return true; + } else if( $wgAutoConfirmAge && ($time - wfTimestampOrNull(TS_UNIX,$age)) < $wgAutoConfirmAge ) { + return true; + } + return false; + } /** * Returns text for the start of the tabular part of RC + * @return string */ - function beginRecentChangesList() { + public function beginRecentChangesList() { $this->rc_cache = array(); $this->rcMoveIndex = 0; $this->rcCacheIndex = 0; @@ -98,8 +123,9 @@ class ChangesList { /** * Returns text for the end of RC + * @return string */ - function endRecentChangesList() { + public function endRecentChangesList() { if( $this->rclistOpen ) { return "\n"; } else { @@ -107,8 +133,7 @@ class ChangesList { } } - - function insertMove( &$s, $rc ) { + protected function insertMove( &$s, $rc ) { # Diff $s .= '(' . $this->message['diff'] . ') ('; # Hist @@ -121,12 +146,11 @@ class ChangesList { $this->skin->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) ); } - function insertDateHeader(&$s, $rc_timestamp) { + protected function insertDateHeader(&$s, $rc_timestamp) { global $wgLang; # Make date header if necessary $date = $wgLang->date( $rc_timestamp, true, true ); - $s = ''; if( $date != $this->lastdate ) { if( '' != $this->lastdate ) { $s .= "\n"; @@ -137,15 +161,16 @@ class ChangesList { } } - function insertLog(&$s, $title, $logtype) { + protected function insertLog(&$s, $title, $logtype) { $logname = LogPage::logName( $logtype ); $s .= '(' . $this->skin->makeKnownLinkObj($title, $logname ) . ')'; } - - function insertDiffHist(&$s, &$rc, $unpatrolled) { + protected function insertDiffHist(&$s, &$rc, $unpatrolled) { # Diff link - if( $rc->mAttribs['rc_type'] == RC_NEW || $rc->mAttribs['rc_type'] == RC_LOG ) { + if( !$this->userCan($rc,Revision::DELETED_TEXT) ) { + $diffLink = $this->message['diff']; + } else if( $rc->mAttribs['rc_type'] == RC_NEW || $rc->mAttribs['rc_type'] == RC_LOG ) { $diffLink = $this->message['diff']; } else { $rcidparam = $unpatrolled @@ -169,38 +194,70 @@ class ChangesList { $s .= ') . . '; } - function insertArticleLink(&$s, &$rc, $unpatrolled, $watched) { + protected function insertArticleLink(&$s, &$rc, $unpatrolled, $watched) { # Article link # If it's a new article, there is no diff link, but if it hasn't been # patrolled yet, we need to give users a way to do so $params = ( $unpatrolled && $rc->mAttribs['rc_type'] == RC_NEW ) ? 'rcid='.$rc->mAttribs['rc_id'] : ''; - $articlelink = ' '. $this->skin->makeKnownLinkObj( $rc->getTitle(), '', $params ); - if($watched) $articlelink = ''.$articlelink.''; + if( $this->isDeleted($rc,Revision::DELETED_TEXT) ) { + $articlelink = $this->skin->makeKnownLinkObj( $rc->getTitle(), '', $params ); + $articlelink = ''.$articlelink.''; + } else { + $articlelink = ' '. $this->skin->makeKnownLinkObj( $rc->getTitle(), '', $params ); + } + if( $watched ) + $articlelink = "{$articlelink}"; global $wgContLang; $articlelink .= $wgContLang->getDirMark(); + wfRunHooks('ChangesListInsertArticleLink', + array(&$this, &$articlelink, &$s, &$rc, $unpatrolled, $watched)); + $s .= ' '.$articlelink; } - function insertTimestamp(&$s, &$rc) { + protected function insertTimestamp(&$s, $rc) { global $wgLang; # Timestamp - $s .= '; ' . $wgLang->time( $rc->mAttribs['rc_timestamp'], true, true ) . ' . . '; + $s .= $this->message['semicolon-separator'] . $wgLang->time( $rc->mAttribs['rc_timestamp'], true, true ) . ' . . '; } /** Insert links to user page, user talk page and eventually a blocking link */ - function insertUserRelatedLinks(&$s, &$rc) { - $s .= $this->skin->userLink( $rc->mAttribs['rc_user'], $rc->mAttribs['rc_user_text'] ); - $s .= $this->skin->userToolLinks( $rc->mAttribs['rc_user'], $rc->mAttribs['rc_user_text'] ); + public function insertUserRelatedLinks(&$s, &$rc) { + if ( $this->isDeleted($rc,Revision::DELETED_USER) ) { + $s .= ' ' . wfMsgHtml('rev-deleted-user') . ''; + } else { + $s .= $this->skin->userLink( $rc->mAttribs['rc_user'], $rc->mAttribs['rc_user_text'] ); + $s .= $this->skin->userToolLinks( $rc->mAttribs['rc_user'], $rc->mAttribs['rc_user_text'] ); + } + } + + /** insert a formatted action */ + protected function insertAction(&$s, &$rc) { + # Add action + if( $rc->mAttribs['rc_type'] == RC_LOG ) { + // log action + if ( $this->isDeleted($rc,LogPage::DELETED_ACTION) ) { + $s .= ' ' . wfMsgHtml('rev-deleted-event') . ''; + } else { + $s .= ' ' . LogPage::actionText( $rc->mAttribs['rc_log_type'], $rc->mAttribs['rc_log_action'], + $rc->getTitle(), $this->skin, LogPage::extractParams($rc->mAttribs['rc_params']), true, true ); + } + } } /** insert a formatted comment */ - function insertComment(&$s, &$rc) { + protected function insertComment(&$s, &$rc) { # Add comment if( $rc->mAttribs['rc_type'] != RC_MOVE && $rc->mAttribs['rc_type'] != RC_MOVE_OVER_REDIRECT ) { - $s .= $this->skin->commentBlock( $rc->mAttribs['rc_comment'], $rc->getTitle() ); + // log comment + if ( $this->isDeleted($rc,Revision::DELETED_COMMENT) ) { + $s .= ' ' . wfMsgHtml('rev-deleted-comment') . ''; + } else { + $s .= $this->skin->commentBlock( $rc->mAttribs['rc_comment'], $rc->getTitle() ); + } } } @@ -208,12 +265,57 @@ class ChangesList { * Check whether to enable recent changes patrol features * @return bool */ - function usePatrol() { - global $wgUseRCPatrol, $wgUser; - return( $wgUseRCPatrol && $wgUser->isAllowed( 'patrol' ) ); + public static function usePatrol() { + global $wgUser; + return $wgUser->useRCPatrol(); + } + + /** + * Returns the string which indicates the number of watching users + */ + protected function numberofWatchingusers( $count ) { + global $wgLang; + static $cache = array(); + if ( $count > 0 ) { + if ( !isset( $cache[$count] ) ) { + $cache[$count] = wfMsgExt('number_of_watching_users_RCview', + array('parsemag', 'escape'), $wgLang->formatNum($count)); + } + return $cache[$count]; + } else { + return ''; + } } + /** + * Determine if said field of a revision is hidden + * @param RCCacheEntry $rc + * @param int $field one of DELETED_* bitfield constants + * @return bool + */ + public static function isDeleted( $rc, $field ) { + return ($rc->mAttribs['rc_deleted'] & $field) == $field; + } + /** + * Determine if the current user is allowed to view a particular + * field of this revision, if it's marked as deleted. + * @param RCCacheEntry $rc + * @param int $field + * @return bool + */ + public static function userCan( $rc, $field ) { + if( ( $rc->mAttribs['rc_deleted'] & $field ) == $field ) { + global $wgUser; + $permission = ( $rc->mAttribs['rc_deleted'] & Revision::DELETED_RESTRICTED ) == Revision::DELETED_RESTRICTED + ? 'suppressrevision' + : 'deleterevision'; + wfDebug( "Checking for $permission due to $field match on $rc->mAttribs['rc_deleted']\n" ); + return $wgUser->isAllowed( $permission ); + } else { + return true; + } + } } @@ -224,43 +326,48 @@ class OldChangesList extends ChangesList { /** * Format a line using the old system (aka without any javascript). */ - function recentChangesLine( &$rc, $watched = false ) { - global $wgContLang; + public function recentChangesLine( &$rc, $watched = false ) { + global $wgContLang, $wgRCShowChangedSize, $wgUser; $fname = 'ChangesList::recentChangesLineOld'; wfProfileIn( $fname ); - # Extract DB fields into local scope + // FIXME: Would be good to replace this extract() call with something that explicitly initializes local variables. extract( $rc->mAttribs ); - $curIdEq = 'curid=' . $rc_cur_id; # Should patrol-related stuff be shown? - $unpatrolled = $this->usePatrol() && $rc_patrolled == 0; + $unpatrolled = $wgUser->useRCPatrol() && $rc_patrolled == 0; - $this->insertDateHeader($s,$rc_timestamp); + $dateheader = ""; // $s now contains only
  • ...
  • , for hooks' convenience. + $this->insertDateHeader($dateheader,$rc_timestamp); - $s .= '
  • '; + $s = '
  • '; - // moved pages + // Moved pages if( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) { $this->insertMove( $s, $rc ); - // log entries - } elseif ( $rc_namespace == NS_SPECIAL ) { + // Log entries + } elseif( $rc_log_type ) { + $logtitle = Title::newFromText( "Log/$rc_log_type", NS_SPECIAL ); + $this->insertLog( $s, $logtitle, $rc_log_type ); + // Log entries (old format) or log targets, and special pages + } elseif( $rc_namespace == NS_SPECIAL ) { list( $specialName, $specialSubpage ) = SpecialPage::resolveAliasWithSubpage( $rc_title ); if ( $specialName == 'Log' ) { $this->insertLog( $s, $rc->getTitle(), $specialSubpage ); } else { wfDebug( "Unexpected special page in recentchanges\n" ); } - // all other stuff + // Regular entries } else { wfProfileIn($fname.'-page'); $this->insertDiffHist($s, $rc, $unpatrolled); - # M, N, b and ! (minor, new, bot and unpatrolled) - $s .= ' ' . $this->recentChangesFlags( $rc_type == RC_NEW, $rc_minor, $unpatrolled, '', $rc_bot ); + $newbie = self::userIsNew( $rc->mAttribs ); + $s .= $this->recentChangesFlags( $rc_type == RC_NEW, $rc_minor, $unpatrolled, '', + $rc_bot, $newbie ); $this->insertArticleLink($s, $rc, $unpatrolled, $watched); wfProfileOut($fname.'-page'); @@ -269,19 +376,32 @@ class OldChangesList extends ChangesList { wfProfileIn( $fname.'-rest' ); $this->insertTimestamp($s,$rc); + + if( $wgRCShowChangedSize ) { + $s .= ( $rc->getCharacterDifference() == '' ? '' : $rc->getCharacterDifference() . ' . . ' ); + } + # User tool links $this->insertUserRelatedLinks($s,$rc); + # Log action text (if any) + $this->insertAction($s, $rc); + # Edit or log comment $this->insertComment($s, $rc); + # Mark revision as deleted if so + if ( !$rc_log_type && $this->isDeleted($rc,Revision::DELETED_TEXT) ) + $s .= ' ' . wfMsgHtml( 'deletedrev' ) . ''; if($rc->numberofWatchingusers > 0) { $s .= ' ' . wfMsg('number_of_watching_users_RCview', $wgContLang->formatNum($rc->numberofWatchingusers)); } $s .= "
  • \n"; + wfRunHooks('OldChangesListRecentChangesLine', array(&$this, &$s, &$rc)); + wfProfileOut( $fname.'-rest' ); wfProfileOut( $fname ); - return $s; + return $dateheader . $s; } } @@ -293,13 +413,14 @@ class EnhancedChangesList extends ChangesList { /** * Format a line for enhanced recentchange (aka with javascript and block of lines). */ - function recentChangesLine( &$baseRC, $watched = false ) { - global $wgLang, $wgContLang; + public function recentChangesLine( &$baseRC, $watched = false ) { + global $wgLang, $wgContLang, $wgUser; # Create a specialised object $rc = RCCacheEntry::newFromParent( $baseRC ); # Extract fields from DB into the function scope (rc_xxxx variables) + // FIXME: Would be good to replace this extract() call with something that explicitly initializes local variables. extract( $rc->mAttribs ); $curIdEq = 'curid=' . $rc_cur_id; @@ -315,17 +436,20 @@ class EnhancedChangesList extends ChangesList { } # Should patrol-related stuff be shown? - if( $this->usePatrol() ) { + if( $wgUser->useRCPatrol() ) { $rc->unpatrolled = !$rc_patrolled; } else { $rc->unpatrolled = false; } + $showdifflinks = true; # Make article link + // Page moves if( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) { $msg = ( $rc_type == RC_MOVE ) ? "1movedto2" : "1movedto2_redir"; $clink = wfMsg( $msg, $this->skin->makeKnownLinkObj( $rc->getTitle(), '', 'redirect=no' ), $this->skin->makeKnownLinkObj( $rc->getMovedToTitle(), '' ) ); + // Log entries (old format) and special pages } elseif( $rc_namespace == NS_SPECIAL ) { list( $specialName, $logtype ) = SpecialPage::resolveAliasWithSubpage( $rc_title ); if ( $specialName == 'Log' ) { @@ -336,13 +460,28 @@ class EnhancedChangesList extends ChangesList { wfDebug( "Unexpected special page in recentchanges\n" ); $clink = ''; } - } elseif( $rc->unpatrolled && $rc_type == RC_NEW ) { - # Unpatrolled new page, give rc_id in query + // New unpatrolled pages + } else if( $rc->unpatrolled && $rc_type == RC_NEW ) { $clink = $this->skin->makeKnownLinkObj( $rc->getTitle(), '', "rcid={$rc_id}" ); + // Log entries + } else if( $rc_type == RC_LOG ) { + if( $rc_log_type ) { + $logtitle = SpecialPage::getTitleFor( 'Log', $rc_log_type ); + $clink = '(' . $this->skin->makeKnownLinkObj( $logtitle, LogPage::logName($rc_log_type) ) . ')'; + } else { + $clink = $this->skin->makeLinkObj( $rc->getTitle(), '' ); + } + $watched = false; + // Edits } else { $clink = $this->skin->makeKnownLinkObj( $rc->getTitle(), '' ); } + # Don't show unusable diff links + if ( !ChangesList::userCan($rc,Revision::DELETED_TEXT) ) { + $showdifflinks = false; + } + $time = $wgContLang->time( $rc_timestamp, true, true ); $rc->watched = $watched; $rc->link = $clink; @@ -359,7 +498,12 @@ class EnhancedChangesList extends ChangesList { $querydiff = $curIdEq."&diff=$rc_this_oldid&oldid=$rc_last_oldid$rcIdQuery"; $aprops = ' tabindex="'.$baseRC->counter.'"'; $curLink = $this->skin->makeKnownLinkObj( $rc->getTitle(), $this->message['cur'], $querycur, '' ,'', $aprops ); - if( $rc_type == RC_NEW || $rc_type == RC_LOG || $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) { + + # Make "diff" an "cur" links + if( !$showdifflinks ) { + $curLink = $this->message['cur']; + $diffLink = $this->message['diff']; + } else if( $rc_type == RC_NEW || $rc_type == RC_LOG || $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) { if( $rc_type != RC_NEW ) { $curLink = $this->message['cur']; } @@ -369,21 +513,27 @@ class EnhancedChangesList extends ChangesList { } # Make "last" link - if( $rc_last_oldid == 0 || $rc_type == RC_LOG || $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) { + if( !$showdifflinks ) { + $lastLink = $this->message['last']; + } else if( $rc_last_oldid == 0 || $rc_type == RC_LOG || $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) { $lastLink = $this->message['last']; } else { $lastLink = $this->skin->makeKnownLinkObj( $rc->getTitle(), $this->message['last'], - $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid . $rcIdQuery ); + $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid . $rcIdQuery ); } - $rc->userlink = $this->skin->userLink( $rc_user, $rc_user_text ); + # Make user links + if( $this->isDeleted($rc,Revision::DELETED_USER) ) { + $rc->userlink = ' ' . wfMsgHtml('rev-deleted-user') . ''; + } else { + $rc->userlink = $this->skin->userLink( $rc_user, $rc_user_text ); + $rc->usertalklink = $this->skin->userToolLinks( $rc_user, $rc_user_text ); + } $rc->lastlink = $lastLink; $rc->curlink = $curLink; $rc->difflink = $diffLink; - $rc->usertalklink = $this->skin->userToolLinks( $rc_user, $rc_user_text ); - # Put accumulated information into the cache, for later display # Page moves go on their own line $title = $rc->getTitle(); @@ -392,7 +542,11 @@ class EnhancedChangesList extends ChangesList { # Use an @ character to prevent collision with page names $this->rc_cache['@@' . ($this->rcMoveIndex++)] = array($rc); } else { - if( !isset ( $this->rc_cache[$secureName] ) ) { + # Logs are grouped by type + if( $rc_type == RC_LOG ){ + $secureName = SpecialPage::getTitleFor( 'Log', $rc_log_type )->getPrefixedDBkey(); + } + if( !isset( $this->rc_cache[$secureName] ) ) { $this->rc_cache[$secureName] = array(); } array_push( $this->rc_cache[$secureName], $rc ); @@ -403,20 +557,28 @@ class EnhancedChangesList extends ChangesList { /** * Enhanced RC group */ - function recentChangesBlockGroup( $block ) { - global $wgContLang; - $r = ''; + protected function recentChangesBlockGroup( $block ) { + global $wgLang, $wgContLang, $wgRCShowChangedSize; + $r = ''; # Collate list of users - $isnew = false; - $unpatrolled = false; $userlinks = array(); + # Other properties + $unpatrolled = $isnew = $newbie = false; + $curId = $currentRevision = 0; + # Some catalyst variables... + $namehidden = true; + $alllogs = true; foreach( $block as $rcObj ) { $oldid = $rcObj->mAttribs['rc_last_oldid']; - $newid = $rcObj->mAttribs['rc_this_oldid']; - if( $rcObj->mAttribs['rc_new'] ) { + if( $rcObj->mAttribs['rc_type'] == RC_NEW ) { $isnew = true; } + // If all log actions to this page were hidden, then don't + // give the name of the affected page for this block! + if( !$this->isDeleted( $rcObj, LogPage::DELETED_ACTION ) ) { + $namehidden = false; + } $u = $rcObj->userlink; if( !isset( $userlinks[$u] ) ) { $userlinks[$u] = 0; @@ -424,6 +586,21 @@ class EnhancedChangesList extends ChangesList { if( $rcObj->unpatrolled ) { $unpatrolled = true; } + if( $rcObj->mAttribs['rc_type'] != RC_LOG ) { + $alllogs = false; + } + if( self::userIsNew( $rcObj->mAttribs ) ) { + $newbie = true; + } + # Get the latest entry with a page_id and oldid + # since logs may not have these. + if( !$curId && $rcObj->mAttribs['rc_cur_id'] ) { + $curId = $rcObj->mAttribs['rc_cur_id']; + } + if( !$currentRevision && $rcObj->mAttribs['rc_this_oldid'] ) { + $currentRevision = $rcObj->mAttribs['rc_this_oldid']; + } + $bot = $rcObj->mAttribs['rc_bot']; $userlinks[$u]++; } @@ -436,12 +613,12 @@ class EnhancedChangesList extends ChangesList { $text = $userlink; $text .= $wgContLang->getDirMark(); if( $count > 1 ) { - $text .= ' ('.$count.'×)'; + $text .= ' (' . $wgLang->formatNum( $count ) . '×)'; } array_push( $users, $text ); } - $users = ' ['.implode('; ',$users).']'; + $users = ' [' . implode( $this->message['semicolon-separator'], $users ) . ']'; # Arrow $rci = 'RCI'.$this->rcCacheIndex; @@ -450,89 +627,152 @@ class EnhancedChangesList extends ChangesList { $toggleLink = "javascript:toggleVisibility('$rci','$rcm','$rcl')"; $tl = '' . $this->sideArrow() . ''; $tl .= ''; - $r .= $tl; + $r .= '
    '.$tl.' '; # Main line - $r .= ''; - $r .= $this->recentChangesFlags( $isnew, false, $unpatrolled, ' ', $bot ); + $r .= $this->recentChangesFlags( $isnew, false, $unpatrolled, ' ', $bot, $newbie ); # Timestamp - $r .= ' '.$block[0]->timestamp.' '; - $r .= ''; + $r .= ' '.$block[0]->timestamp.' '; # Article link - $r .= $this->maybeWatchedLink( $block[0]->link, $block[0]->watched ); + if( $namehidden ) { + $r .= ' ' . wfMsgHtml('rev-deleted-event') . ''; + } else { + $r .= $this->maybeWatchedLink( $block[0]->link, $block[0]->watched ); + } + $r .= $wgContLang->getDirMark(); - $curIdEq = 'curid=' . $block[0]->mAttribs['rc_cur_id']; - $currentRevision = $block[0]->mAttribs['rc_this_oldid']; - if( $block[0]->mAttribs['rc_type'] != RC_LOG ) { - # Changes - $r .= ' ('.count($block).' '; - if( $isnew ) { - $r .= $this->message['changes']; + $curIdEq = 'curid=' . $curId; + # Changes message + $n = count($block); + static $nchanges = array(); + if ( !isset( $nchanges[$n] ) ) { + $nchanges[$n] = wfMsgExt( 'nchanges', array( 'parsemag', 'escape' ), $wgLang->formatNum( $n ) ); + } + # Total change link + $r .= ' '; + if( !$alllogs ) { + $r .= '('; + if( !ChangesList::userCan($rcObj,Revision::DELETED_TEXT) ) { + $r .= $nchanges[$n]; + } else if( $isnew ) { + $r .= $nchanges[$n]; } else { $r .= $this->skin->makeKnownLinkObj( $block[0]->getTitle(), - $this->message['changes'], $curIdEq."&diff=$currentRevision&oldid=$oldid" ); + $nchanges[$n], $curIdEq."&diff=$currentRevision&oldid=$oldid" ); + } + $r .= ') . . '; + } + + # Character difference (does not apply if only log items) + if( $wgRCShowChangedSize && !$alllogs ) { + $last = 0; + $first = count($block) - 1; + # Some events (like logs) have an "empty" size, so we need to skip those... + while( $last < $first && $block[$last]->mAttribs['rc_new_len'] === NULL ) { + $last++; + } + while( $first > $last && $block[$first]->mAttribs['rc_old_len'] === NULL ) { + $first--; + } + # Get net change + $chardiff = $rcObj->getCharacterDifference( $block[$first]->mAttribs['rc_old_len'], + $block[$last]->mAttribs['rc_new_len'] ); + + if( $chardiff == '' ) { + $r .= ' '; + } else { + $r .= ' ' . $chardiff. ' . . '; } - $r .= '; '; + } - # History - $r .= $this->skin->makeKnownLinkObj( $block[0]->getTitle(), - $this->message['history'], $curIdEq.'&action=history' ); - $r .= ')'; + # History + if( $alllogs ) { + // don't show history link for logs + } else if( $namehidden || !$block[0]->getTitle()->exists() ) { + $r .= '(' . $this->message['history'] . ')'; + } else { + $r .= '(' . $this->skin->makeKnownLinkObj( $block[0]->getTitle(), + $this->message['history'], $curIdEq.'&action=history' ) . ')'; } $r .= $users; + $r .= $this->numberofWatchingusers($block[0]->numberofWatchingusers); - if($block[0]->numberofWatchingusers > 0) { - global $wgContLang; - $r .= wfMsg('number_of_watching_users_RCview', $wgContLang->formatNum($block[0]->numberofWatchingusers)); - } - $r .= "
    \n"; + $r .= "
    \n"; # Sub-entries - $r .= '