diff options
author | Luke Shumaker <lukeshu@sbcglobal.net> | 2016-05-01 15:12:12 -0400 |
---|---|---|
committer | Luke Shumaker <lukeshu@sbcglobal.net> | 2016-05-01 15:12:12 -0400 |
commit | c9aa36da061816dee256a979c2ff8d2ee41824d9 (patch) | |
tree | 29f7002b80ee984b488bd047dbbd80b36bf892e9 /includes/changes/ChangesList.php | |
parent | b4274e0e33eafb5e9ead9d949ebf031a9fb8363b (diff) | |
parent | d1ba966140d7a60cd5ae4e8667ceb27c1a138592 (diff) |
Merge branch 'archwiki'
# Conflicts:
# skins/ArchLinux.php
# skins/ArchLinux/archlogo.gif
Diffstat (limited to 'includes/changes/ChangesList.php')
-rw-r--r-- | includes/changes/ChangesList.php | 250 |
1 files changed, 147 insertions, 103 deletions
diff --git a/includes/changes/ChangesList.php b/includes/changes/ChangesList.php index bf800c46..03d1289f 100644 --- a/includes/changes/ChangesList.php +++ b/includes/changes/ChangesList.php @@ -23,20 +23,26 @@ */ class ChangesList extends ContextSource { - /** * @var Skin */ public $skin; protected $watchlist = false; - + protected $lastdate; protected $message; + protected $rc_cache; + protected $rcCacheIndex; + protected $rclistOpen; + protected $rcMoveIndex; + + /** @var MapCacheLRU */ + protected $watchingCache; /** * Changeslist constructor * - * @param $obj Skin or IContextSource + * @param Skin|IContextSource $obj */ public function __construct( $obj ) { if ( $obj instanceof IContextSource ) { @@ -47,27 +53,15 @@ class ChangesList extends ContextSource { $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 string|User $unused Unused - * @return ChangesList|EnhancedChangesList|OldChangesList derivative - */ - public static function newFromUser( $unused ) { - wfDeprecated( __METHOD__, '1.18' ); - return self::newFromContext( RequestContext::getMain() ); + $this->watchingCache = new MapCacheLRU( 50 ); } /** * 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 + * @param IContextSource $context + * @return ChangesList */ public static function newFromContext( IContextSource $context ) { $user = $context->getUser(); @@ -75,6 +69,7 @@ class ChangesList extends ContextSource { $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; @@ -83,13 +78,21 @@ class ChangesList extends ContextSource { /** * Sets the list to use a "<li class='watchlist-(namespace)-(page)'>" tag - * @param $value Boolean + * @param bool $value */ public function setWatchlistDivs( $value = true ) { $this->watchlist = $value; } /** + * @return bool True when setWatchlistDivs has been called + * @since 1.23 + */ + public function isWatchlist() { + return (bool)$this->watchlist; + } + + /** * 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 */ @@ -107,17 +110,17 @@ class ChangesList extends ContextSource { /** * Returns the appropriate flags for new page, minor change and patrolling * @param array $flags Associative array of 'flag' => Bool - * @param string $nothing to use for empty space - * @return String + * @param string $nothing To use for empty space + * @return string */ public function recentChangesFlags( $flags, $nothing = ' ' ) { - global $wgRecentChangesFlags; $f = ''; - foreach ( array_keys( $wgRecentChangesFlags ) as $flag ) { + foreach ( array_keys( $this->getConfig()->get( 'RecentChangesFlags' ) ) as $flag ) { $f .= isset( $flags[$flag] ) && $flags[$flag] ? self::flag( $flag ) : $nothing; } + return $f; } @@ -128,7 +131,7 @@ class ChangesList extends ContextSource { * "!" respectively, plus it will have an appropriate title and class. * * @param string $flag One key of $wgRecentChangesFlags - * @return String: Raw HTML + * @return string Raw HTML */ public static function flag( $flag ) { static $flagInfos = null; @@ -153,14 +156,14 @@ class ChangesList extends ContextSource { $flag = $map[$flag]; } - return "<abbr class='" . $flagInfos[$flag]['class'] . "' title='" . $flagInfos[$flag]['title'] . "'>" . - $flagInfos[$flag]['letter'] . + return "<abbr class='" . $flagInfos[$flag]['class'] . "' title='" . + $flagInfos[$flag]['title'] . "'>" . $flagInfos[$flag]['letter'] . '</abbr>'; } /** * Returns text for the start of the tabular part of RC - * @return String + * @return string */ public function beginRecentChangesList() { $this->rc_cache = array(); @@ -169,19 +172,25 @@ class ChangesList extends ContextSource { $this->lastdate = ''; $this->rclistOpen = false; $this->getOutput()->addModuleStyles( 'mediawiki.special.changeslist' ); - return ''; + + return '<div class="mw-changeslist">'; + } + + /** + * @param ResultWrapper|array $rows + */ + public function initChangesListRows( $rows ) { + wfRunHooks( 'ChangesListInitRows', array( $this, $rows ) ); } /** * Show formatted char difference - * @param $old Integer: bytes - * @param $new Integer: bytes - * @param $context IContextSource context to use - * @return String + * @param int $old Number of bytes + * @param int $new Number of bytes + * @param IContextSource $context + * @return string */ public static function showCharacterDifference( $old, $new, IContextSource $context = null ) { - global $wgRCChangedSizeThreshold, $wgMiserMode; - if ( !$context ) { $context = RequestContext::getMain(); } @@ -191,10 +200,11 @@ class ChangesList extends ContextSource { $szdiff = $new - $old; $lang = $context->getLanguage(); + $config = $context->getConfig(); $code = $lang->getCode(); static $fastCharDiff = array(); if ( !isset( $fastCharDiff[$code] ) ) { - $fastCharDiff[$code] = $wgMiserMode || $context->msg( 'rc-change-size' )->plain() === '$1'; + $fastCharDiff[$code] = $config->get( 'MiserMode' ) || $context->msg( 'rc-change-size' )->plain() === '$1'; } $formattedSize = $lang->formatNum( $szdiff ); @@ -203,7 +213,7 @@ class ChangesList extends ContextSource { $formattedSize = $context->msg( 'rc-change-size', $formattedSize )->text(); } - if ( abs( $szdiff ) > abs( $wgRCChangedSizeThreshold ) ) { + if ( abs( $szdiff ) > abs( $config->get( 'RCChangedSizeThreshold' ) ) ) { $tag = 'strong'; } else { $tag = 'span'; @@ -211,12 +221,10 @@ class ChangesList extends ContextSource { if ( $szdiff === 0 ) { $formattedSizeClass = 'mw-plusminus-null'; - } - if ( $szdiff > 0 ) { + } elseif ( $szdiff > 0 ) { $formattedSize = '+' . $formattedSize; $formattedSizeClass = 'mw-plusminus-pos'; - } - if ( $szdiff < 0 ) { + } else { $formattedSizeClass = 'mw-plusminus-neg'; } @@ -230,8 +238,8 @@ class ChangesList extends ContextSource { /** * 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 + * @param RecentChange $old + * @param RecentChange $new Last change to use, if not provided, $old will be used * @return string HTML fragment */ public function formatCharacterDifference( RecentChange $old, RecentChange $new = null ) { @@ -252,19 +260,18 @@ class ChangesList extends ContextSource { /** * Returns text for the end of RC - * @return String + * @return string */ public function endRecentChangesList() { - if ( $this->rclistOpen ) { - return "</ul>\n"; - } else { - return ''; - } + $out = $this->rclistOpen ? "</ul>\n" : ''; + $out .= '</div>'; + + return $out; } /** * @param string $s HTML to update - * @param $rc_timestamp mixed + * @param mixed $rc_timestamp */ public function insertDateHeader( &$s, $rc_timestamp ) { # Make date header if necessary @@ -281,8 +288,8 @@ class ChangesList extends ContextSource { /** * @param string $s HTML to update - * @param $title Title - * @param $logtype string + * @param Title $title + * @param string $logtype */ public function insertLog( &$s, $title, $logtype ) { $page = new LogPage( $logtype ); @@ -292,8 +299,8 @@ class ChangesList extends ContextSource { /** * @param string $s HTML to update - * @param $rc RecentChange - * @param $unpatrolled + * @param RecentChange $rc + * @param bool $unpatrolled */ public function insertDiffHist( &$s, &$rc, $unpatrolled ) { # Diff link @@ -326,17 +333,22 @@ class ChangesList extends ContextSource { 'action' => 'history' ) ); - $s .= $this->msg( 'parentheses' )->rawParams( $diffhist )->escaped() . ' <span class="mw-changeslist-separator">. .</span> '; + // @todo FIXME: Hard coded ". .". Is there a message for this? Should there be? + $s .= $this->msg( 'parentheses' )->rawParams( $diffhist )->escaped() . + ' <span class="mw-changeslist-separator">. .</span> '; } /** * @param string $s HTML to update - * @param $rc RecentChange - * @param $unpatrolled - * @param $watched + * @param RecentChange $rc + * @param bool $unpatrolled + * @param bool $watched */ public function insertArticleLink( &$s, &$rc, $unpatrolled, $watched ) { $params = array(); + if ( $rc->getTitle()->isRedirect() ) { + $params = array( 'redirect' => 'no' ); + } $articlelink = Linker::linkKnown( $rc->getTitle(), @@ -362,19 +374,23 @@ class ChangesList extends ContextSource { * Get the timestamp from $rc formatted with current user's settings * and a separator * - * @param $rc RecentChange + * @param RecentChange $rc * @return string HTML fragment */ public function getTimestamp( $rc ) { + // @todo FIXME: Hard coded ". .". Is there a message for this? Should there be? return $this->message['semicolon-separator'] . '<span class="mw-changeslist-date">' . - $this->getLanguage()->userTime( $rc->mAttribs['rc_timestamp'], $this->getUser() ) . '</span> <span class="mw-changeslist-separator">. .</span> '; + $this->getLanguage()->userTime( + $rc->mAttribs['rc_timestamp'], + $this->getUser() + ) . '</span> <span class="mw-changeslist-separator">. .</span> '; } /** * Insert time timestamp string from $rc into $s * * @param string $s HTML to update - * @param $rc RecentChange + * @param RecentChange $rc */ public function insertTimestamp( &$s, $rc ) { $s .= $this->getTimestamp( $rc ); @@ -383,12 +399,13 @@ class ChangesList extends ContextSource { /** * Insert links to user page, user talk page and eventually a blocking link * - * @param &$s String HTML to update - * @param &$rc RecentChange + * @param string &$s HTML to update + * @param RecentChange &$rc */ public function insertUserRelatedLinks( &$s, &$rc ) { if ( $this->isDeleted( $rc, Revision::DELETED_USER ) ) { - $s .= ' <span class="history-deleted">' . $this->msg( 'rev-deleted-user' )->escaped() . '</span>'; + $s .= ' <span class="history-deleted">' . + $this->msg( 'rev-deleted-user' )->escaped() . '</span>'; } else { $s .= $this->getLanguage()->getDirMark() . Linker::userLink( $rc->mAttribs['rc_user'], $rc->mAttribs['rc_user_text'] ); @@ -399,7 +416,7 @@ class ChangesList extends ContextSource { /** * Insert a formatted action * - * @param $rc RecentChange + * @param RecentChange $rc * @return string */ public function insertLogEntry( $rc ) { @@ -407,30 +424,29 @@ class ChangesList extends ContextSource { $formatter->setContext( $this->getContext() ); $formatter->setShowUserToolLinks( true ); $mark = $this->getLanguage()->getDirMark(); + return $formatter->getActionText() . " $mark" . $formatter->getComment(); } /** * Insert a formatted comment - * @param $rc RecentChange + * @param RecentChange $rc * @return string */ public function insertComment( $rc ) { - if ( $rc->mAttribs['rc_type'] != RC_MOVE && $rc->mAttribs['rc_type'] != RC_MOVE_OVER_REDIRECT ) { - if ( $this->isDeleted( $rc, Revision::DELETED_COMMENT ) ) { - return ' <span class="history-deleted">' . $this->msg( 'rev-deleted-comment' )->escaped() . '</span>'; - } else { - return Linker::commentBlock( $rc->mAttribs['rc_comment'], $rc->getTitle() ); - } + if ( $this->isDeleted( $rc, Revision::DELETED_COMMENT ) ) { + return ' <span class="history-deleted">' . + $this->msg( 'rev-deleted-comment' )->escaped() . '</span>'; + } else { + return Linker::commentBlock( $rc->mAttribs['rc_comment'], $rc->getTitle() ); } - return ''; } /** * Check whether to enable recent changes patrol features * * @deprecated since 1.22 - * @return Boolean + * @return bool */ public static function usePatrol() { global $wgUser; @@ -442,15 +458,18 @@ class ChangesList extends ContextSource { /** * Returns the string which indicates the number of watching users + * @param int $count Number of user watching a page * @return string */ protected function numberofWatchingusers( $count ) { - static $cache = array(); + $cache = $this->watchingCache; if ( $count > 0 ) { - if ( !isset( $cache[$count] ) ) { - $cache[$count] = $this->msg( 'number_of_watching_users_RCview' )->numParams( $count )->escaped(); + if ( !$cache->has( $count ) ) { + $cache->set( $count, $this->msg( 'number_of_watching_users_RCview' ) + ->numParams( $count )->escaped() ); } - return $cache[$count]; + + return $cache->get( $count ); } else { return ''; } @@ -458,9 +477,9 @@ class ChangesList extends ContextSource { /** * Determine if said field of a revision is hidden - * @param $rc RCCacheEntry - * @param $field Integer: one of DELETED_* bitfield constants - * @return Boolean + * @param RCCacheEntry|RecentChange $rc + * @param int $field One of DELETED_* bitfield constants + * @return bool */ public static function isDeleted( $rc, $field ) { return ( $rc->mAttribs['rc_deleted'] & $field ) == $field; @@ -469,10 +488,10 @@ class ChangesList extends ContextSource { /** * Determine if the current user is allowed to view a particular * field of this revision, if it's marked as deleted. - * @param $rc RCCacheEntry - * @param $field Integer - * @param $user User object to check, or null to use $wgUser - * @return Boolean + * @param RCCacheEntry|RecentChange $rc + * @param int $field + * @param User $user User object to check, or null to use $wgUser + * @return bool */ public static function userCan( $rc, $field, User $user = null ) { if ( $rc->mAttribs['rc_type'] == RC_LOG ) { @@ -483,8 +502,8 @@ class ChangesList extends ContextSource { } /** - * @param $link string - * @param $watched bool + * @param string $link + * @param bool $watched * @return string */ protected function maybeWatchedLink( $link, $watched = false ) { @@ -497,16 +516,20 @@ class ChangesList extends ContextSource { /** Inserts a rollback link * - * @param $s string - * @param $rc RecentChange + * @param string $s + * @param RecentChange $rc */ public function insertRollback( &$s, &$rc ) { - if ( $rc->mAttribs['rc_type'] == RC_EDIT && $rc->mAttribs['rc_this_oldid'] && $rc->mAttribs['rc_cur_id'] ) { + if ( $rc->mAttribs['rc_type'] == RC_EDIT + && $rc->mAttribs['rc_this_oldid'] + && $rc->mAttribs['rc_cur_id'] + ) { $page = $rc->getTitle(); /** Check for rollback and edit permissions, disallow special pages, and only - * show a link on the top-most revision */ - if ( $this->getUser()->isAllowed( 'rollback' ) && $rc->mAttribs['page_latest'] == $rc->mAttribs['rc_this_oldid'] ) - { + * show a link on the top-most revision */ + if ( $this->getUser()->isAllowed( 'rollback' ) + && $rc->mAttribs['page_latest'] == $rc->mAttribs['rc_this_oldid'] + ) { $rev = new Revision( array( 'title' => $page, 'id' => $rc->mAttribs['rc_this_oldid'], @@ -520,16 +543,19 @@ class ChangesList extends ContextSource { } /** - * @param $s string - * @param $rc RecentChange - * @param $classes + * @param string $s + * @param RecentChange $rc + * @param array $classes */ public function insertTags( &$s, &$rc, &$classes ) { if ( empty( $rc->mAttribs['ts_tags'] ) ) { return; } - list( $tagSummary, $newClasses ) = ChangeTags::formatSummaryRow( $rc->mAttribs['ts_tags'], 'changeslist' ); + list( $tagSummary, $newClasses ) = ChangeTags::formatSummaryRow( + $rc->mAttribs['ts_tags'], + 'changeslist' + ); $classes = array_merge( $classes, $newClasses ); $s .= ' ' . $tagSummary; } @@ -539,14 +565,32 @@ class ChangesList extends ContextSource { } protected function showAsUnpatrolled( RecentChange $rc ) { - $unpatrolled = false; - if ( !$rc->mAttribs['rc_patrolled'] ) { - if ( $this->getUser()->useRCPatrol() ) { - $unpatrolled = true; - } elseif ( $this->getUser()->useNPPatrol() && $rc->mAttribs['rc_type'] == RC_NEW ) { - $unpatrolled = true; + return self::isUnpatrolled( $rc, $this->getUser() ); + } + + /** + * @param object|RecentChange $rc Database row from recentchanges or a RecentChange object + * @param User $user + * @return bool + */ + public static function isUnpatrolled( $rc, User $user ) { + if ( $rc instanceof RecentChange ) { + $isPatrolled = $rc->mAttribs['rc_patrolled']; + $rcType = $rc->mAttribs['rc_type']; + } else { + $isPatrolled = $rc->rc_patrolled; + $rcType = $rc->rc_type; + } + + if ( !$isPatrolled ) { + if ( $user->useRCPatrol() ) { + return true; + } + if ( $user->useNPPatrol() && $rcType == RC_NEW ) { + return true; } } - return $unpatrolled; + + return false; } } |