X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FChangesList.php;h=bad9445a01ec98c083fa31dcd65d4f5a210667f3;hb=1dfc87b4cba658d178bcd9bb802bb818fc5acd8f;hp=0f814f0c3ad6ff1921cb567aa5d9e22aa02f156e;hpb=11337038b38b7b2bc586444ce82215fbef74f787;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/ChangesList.php b/includes/ChangesList.php index 0f814f0c3a..bad9445a01 100644 --- a/includes/ChangesList.php +++ b/includes/ChangesList.php @@ -1,16 +1,7 @@ mAttribs = $rc->mAttribs; $rc2->mExtra = $rc->mExtra; @@ -28,24 +18,38 @@ 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(); } - function newFromUser( &$user ) { - $sk =& $user->getSkin(); - if( $user->getOption('usenewrc') ) { - return new EnhancedChangesList( $sk ); + /** + * Fetch an appropriate changes list class for the specified user + * Some users might want to use an enhanced list format, for instance + * + * @param $user User to fetch the list class for + * @return ChangesList derivative + */ + public static function newFromUser( &$user ) { + $sk = $user->getSkin(); + $list = NULL; + if( wfRunHooks( 'FetchChangesList', array( &$user, &$sk, &$list ) ) ) { + return $user->getOption( 'usenewrc' ) ? new EnhancedChangesList( $sk ) : new OldChangesList( $sk ); } else { - return new OldChangesList( $sk ); + return $list; } } @@ -53,32 +57,41 @@ 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' ) as $msg ) { - $this->message[$msg] = wfMsg( $msg ); + foreach( explode(' ', 'cur diff hist minoreditletter newpageletter last '. + 'blocklink history boteditletter semicolon-separator' ) as $msg ) { + $this->message[$msg] = wfMsgExt( $msg, array( 'escapenoentities' ) ); } } } /** - * Returns the appropiate flags for new page, minor change and patrolling + * 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 + * @return string */ - function recentChangesFlags( $new, $minor, $patrolled, $nothing = ' ' ) { - $f = $new ? '' . wfMsgHtml( 'newpageletter' ) . '' + protected function recentChangesFlags( $new, $minor, $patrolled, $nothing = ' ', $bot = false ) { + $f = $new ? '' . $this->message['newpageletter'] . '' : $nothing; - $f .= $minor ? '' . wfMsgHtml( 'minoreditletter' ) . '' + $f .= $minor ? '' . $this->message['minoreditletter'] . '' : $nothing; + $f .= $bot ? '' . $this->message['boteditletter'] . '' : $nothing; $f .= $patrolled ? '!' : $nothing; return $f; } /** * 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; @@ -89,8 +102,9 @@ class ChangesList { /** * Returns text for the end of RC + * @return string */ - function endRecentChangesList() { + public function endRecentChangesList() { if( $this->rclistOpen ) { return "\n"; } else { @@ -98,8 +112,7 @@ class ChangesList { } } - - function insertMove( &$s, $rc ) { + protected function insertMove( &$s, $rc ) { # Diff $s .= '(' . $this->message['diff'] . ') ('; # Hist @@ -112,7 +125,7 @@ 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 @@ -128,15 +141,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 @@ -160,122 +174,128 @@ 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->userLink( $rc->mAttribs['rc_user'], $rc->mAttribs['rc_user_text'] ); - $s .= $this->userToolLinks( $rc->mAttribs['rc_user'], $rc->mAttribs['rc_user_text'] ); + protected 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() ); + } } } /** - * Check whether to enable RC-Patrol features + * Check whether to enable recent changes patrol features * @return bool */ - function usePatrol() { - global $wgUseRCPatrol, $wgOnlySysopsCanPatrol, $wgUser; - return $wgUseRCPatrol && $wgUser->isLoggedIn() && - ( !$wgOnlySysopsCanPatrol || $wgUser->isAllowed( 'patrol' ) ); + public static function usePatrol() { + global $wgUser; + return $wgUser->useRCPatrol(); } /** - * Make user link (or user contributions for unregistered users) - * @param int $userId - * @param string $userText - * @return string HTML fragment - * @access private + * Returns the string which indicates the number of watching users */ - function userLink( $userId, $userText ) { - $encName = htmlspecialchars( $userText ); - if( $userId == 0 ) { - $contribsPage = Title::makeTitle( NS_SPECIAL, 'Contributions' ); - return $this->skin->makeKnownLinkObj( $contribsPage, - $encName, 'target=' . urlencode( $userText ) ); - } else { - $userPage = Title::makeTitle( NS_USER, $userText ); - return $this->skin->makeLinkObj( $userPage, $encName ); - } - } - - /** - * @param int $userId - * @param string $userText - * @return string HTML fragment with talk and/or block links - * @access private - */ - function userToolLinks( $userId, $userText ) { - global $wgUser, $wgDisableAnonTalk, $wgSysopUserBans; - $talkable = !( $wgDisableAnonTalk && 0 == $userId ); - $blockable = ( $wgSysopUserBans || 0 == $userId ); - - $items = array(); - if( $talkable ) { - $items[] = $this->userTalkLink( $userId, $userText ); - } - if( $blockable && $wgUser->isAllowed( 'block' ) ) { - $items[] = $this->blockLink( $userId, $userText ); - } - - if( $items ) { - return ' (' . implode( ' | ', $items ) . ')'; + 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 ''; } } /** - * @param int $userId - * @param string $userText - * @return string HTML fragment with user talk link - * @access private + * Determine if said field of a revision is hidden + * @param RCCacheEntry $rc + * @param int $field one of DELETED_* bitfield constants + * @return bool */ - function userTalkLink( $userId, $userText ) { - global $wgContLang; - $talkname = $wgContLang->getNsText( NS_TALK ); # use the shorter name - - $userTalkPage = Title::makeTitle( NS_USER_TALK, $userText ); - $userTalkLink = $this->skin->makeLinkObj( $userTalkPage, $talkname ); - return $userTalkLink; + public static function isDeleted( $rc, $field ) { + return ($rc->mAttribs['rc_deleted'] & $field) == $field; } /** - * @param int $userId - * @param string $userText - * @return string HTML fragment with block link - * @access private + * 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 */ - function blockLink( $userId, $userText ) { - $blockPage = Title::makeTitle( NS_SPECIAL, 'Blockip' ); - $blockLink = $this->skin->makeKnownLinkObj( $blockPage, - $this->message['blocklink'], 'ip=' . urlencode( $userText ) ); - return $blockLink; + 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; + } } - } @@ -286,38 +306,46 @@ 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); $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 && preg_match( '!^Log/(.*)$!', $rc_title, $matches ) ) { - $this->insertLog($s, $rc->getTitle(), $matches[1]); - // all other stuff + // 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" ); + } + // Regular entries } else { wfProfileIn($fname.'-page'); $this->insertDiffHist($s, $rc, $unpatrolled); - # M, N and ! (minor, new and unpatrolled) - $s .= ' ' . $this->recentChangesFlags( $rc_type == RC_NEW, $rc_minor, $unpatrolled, '' ); + # M, N, b and ! (minor, new, bot and unpatrolled) + $s .= $this->recentChangesFlags( $rc_type == RC_NEW, $rc_minor, $unpatrolled, '', $rc_bot ); $this->insertArticleLink($s, $rc, $unpatrolled, $watched); wfProfileOut($fname.'-page'); @@ -326,9 +354,20 @@ 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)); } @@ -350,13 +389,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; @@ -372,29 +412,52 @@ 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(), '' ) ); - } elseif( $rc_namespace == NS_SPECIAL && preg_match( '!^Log/(.*)$!', $rc_title, $matches ) ) { - # Log updates, etc - $logtype = $matches[1]; - $logname = LogPage::logName( $logtype ); - $clink = '(' . $this->skin->makeKnownLinkObj( $rc->getTitle(), $logname ) . ')'; - } elseif( $rc->unpatrolled && $rc_type == RC_NEW ) { - # Unpatrolled new page, give rc_id in query + // Log entries (old format) and special pages + } elseif( $rc_namespace == NS_SPECIAL ) { + list( $specialName, $logtype ) = SpecialPage::resolveAliasWithSubpage( $rc_title ); + if ( $specialName == 'Log' ) { + # Log updates, etc + $logname = LogPage::logName( $logtype ); + $clink = '(' . $this->skin->makeKnownLinkObj( $rc->getTitle(), $logname ) . ')'; + } else { + wfDebug( "Unexpected special page in recentchanges\n" ); + $clink = ''; + } + // 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; @@ -402,7 +465,6 @@ class EnhancedChangesList extends ChangesList { $rc->numberofWatchingusers = $baseRC->numberofWatchingusers; # Make "cur" and "diff" links - $titleObj = $rc->getTitle(); if( $rc->unpatrolled ) { $rcIdQuery = "&rcid={$rc_id}"; } else { @@ -412,7 +474,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']; } @@ -422,21 +489,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->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->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(); @@ -445,7 +518,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 ); @@ -456,19 +533,29 @@ class EnhancedChangesList extends ChangesList { /** * Enhanced RC group */ - function recentChangesBlockGroup( $block ) { - $r = ''; + protected function recentChangesBlockGroup( $block ) { + global $wgLang, $wgContLang, $wgRCShowChangedSize; + $r = ''; # Collate list of users - $isnew = false; - $unpatrolled = false; $userlinks = array(); + # Other properties + $unpatrolled = false; + $isnew = 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'] ) { $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; @@ -476,6 +563,19 @@ class EnhancedChangesList extends ChangesList { if( $rcObj->unpatrolled ) { $unpatrolled = true; } + if( $rcObj->mAttribs['rc_type'] != RC_LOG ) { + $alllogs = false; + } + # 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]++; } @@ -485,13 +585,14 @@ class EnhancedChangesList extends ChangesList { $users = array(); foreach( $userlinks as $userlink => $count) { $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; @@ -500,87 +601,151 @@ 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 ); + $r .= $this->recentChangesFlags( $isnew, false, $unpatrolled, ' ', $bot ); # Timestamp - $r .= ' '.$block[0]->timestamp.' '; - $r .= ''; + $r .= ' '.$block[0]->timestamp.' '; # Article link - $r .= $this->maybeWatchedLink( $block[0]->link, $block[0]->watched ); - - $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 .= wfMsg('changes'); + if( $namehidden ) { + $r .= ' ' . wfMsgHtml('rev-deleted-event') . ''; + } else { + $r .= $this->maybeWatchedLink( $block[0]->link, $block[0]->watched ); + } + + $r .= $wgContLang->getDirMark(); + + $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(), + $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 .= $this->skin->makeKnownLinkObj( $block[0]->getTitle(), wfMsg('changes'), - $curIdEq."&diff=$currentRevision&oldid=$oldid" ); + $r .= ' ' . $chardiff. ' . . '; } - $r .= '; '; + } - # History - $r .= $this->skin->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( '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 .= '