summaryrefslogtreecommitdiff
path: root/includes/changes/EnhancedChangesList.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/changes/EnhancedChangesList.php')
-rw-r--r--includes/changes/EnhancedChangesList.php336
1 files changed, 135 insertions, 201 deletions
diff --git a/includes/changes/EnhancedChangesList.php b/includes/changes/EnhancedChangesList.php
index 4c8aa451..4ab77297 100644
--- a/includes/changes/EnhancedChangesList.php
+++ b/includes/changes/EnhancedChangesList.php
@@ -22,11 +22,44 @@
class EnhancedChangesList extends ChangesList {
+ /**
+ * @var RCCacheEntryFactory
+ */
+ protected $cacheEntryFactory;
+
+ /**
+ * @var array Array of array of RCCacheEntry
+ */
protected $rc_cache;
/**
+ * @param IContextSource|Skin $obj
+ */
+ public function __construct( $obj ) {
+ if ( $obj instanceof Skin ) {
+ // @todo: deprecate constructing with Skin
+ $context = $obj->getContext();
+ } else {
+ if ( !$obj instanceof IContextSource ) {
+ throw new MWException( 'EnhancedChangesList must be constructed with a '
+ . 'context source or skin.' );
+ }
+
+ $context = $obj;
+ }
+
+ parent::__construct( $context );
+
+ // message is set by the parent ChangesList class
+ $this->cacheEntryFactory = new RCCacheEntryFactory(
+ $context,
+ $this->message
+ );
+ }
+
+ /**
* Add the JavaScript file for enhanced changeslist
- * @return String
+ * @return string
*/
public function beginRecentChangesList() {
$this->rc_cache = array();
@@ -42,27 +75,29 @@ class EnhancedChangesList extends ChangesList {
'jquery.makeCollapsible',
'mediawiki.icon',
) );
- return '';
+
+ return '<div class="mw-changeslist">';
}
+
/**
* Format a line for enhanced recentchange (aka with javascript and block of lines).
*
- * @param $baseRC RecentChange
- * @param $watched bool
+ * @param RecentChange $baseRC
+ * @param bool $watched
*
* @return string
*/
public function recentChangesLine( &$baseRC, $watched = false ) {
wfProfileIn( __METHOD__ );
- # Create a specialised object
- $rc = RCCacheEntry::newFromParent( $baseRC );
+ $date = $this->getLanguage()->userDate(
+ $baseRC->mAttribs['rc_timestamp'],
+ $this->getUser()
+ );
- $curIdEq = array( 'curid' => $rc->mAttribs['rc_cur_id'] );
+ $ret = '';
# If it's a new day, add the headline and flush the cache
- $date = $this->getLanguage()->userDate( $rc->mAttribs['rc_timestamp'], $this->getUser() );
- $ret = '';
if ( $date != $this->lastdate ) {
# Process current cache
$ret = $this->recentChangesBlock();
@@ -71,128 +106,60 @@ class EnhancedChangesList extends ChangesList {
$this->lastdate = $date;
}
- # Should patrol-related stuff be shown?
- $rc->unpatrolled = $this->showAsUnpatrolled( $rc );
-
- $showdifflinks = true;
- # Make article link
- $type = $rc->mAttribs['rc_type'];
- $logType = $rc->mAttribs['rc_log_type'];
- // Page moves, very old style, not supported anymore
- if ( $type == RC_MOVE || $type == RC_MOVE_OVER_REDIRECT ) {
- // New unpatrolled pages
- } elseif ( $rc->unpatrolled && $type == RC_NEW ) {
- $clink = Linker::linkKnown( $rc->getTitle() );
- // Log entries
- } elseif ( $type == RC_LOG ) {
- if ( $logType ) {
- $logtitle = SpecialPage::getTitleFor( 'Log', $logType );
- $logpage = new LogPage( $logType );
- $logname = $logpage->getName()->escaped();
- $clink = $this->msg( 'parentheses' )->rawParams( Linker::linkKnown( $logtitle, $logname ) )->escaped();
- } else {
- $clink = Linker::link( $rc->getTitle() );
- }
- $watched = false;
- // Log entries (old format) and special pages
- } elseif ( $rc->mAttribs['rc_namespace'] == NS_SPECIAL ) {
- wfDebug( "Unexpected special page in recentchanges\n" );
- $clink = '';
- // Edits
- } else {
- $clink = Linker::linkKnown( $rc->getTitle() );
- }
+ $cacheEntry = $this->cacheEntryFactory->newFromRecentChange( $baseRC, $watched );
+ $this->addCacheEntry( $cacheEntry );
- # Don't show unusable diff links
- if ( !ChangesList::userCan( $rc, Revision::DELETED_TEXT, $this->getUser() ) ) {
- $showdifflinks = false;
- }
+ wfProfileOut( __METHOD__ );
- $time = $this->getLanguage()->userTime( $rc->mAttribs['rc_timestamp'], $this->getUser() );
- $rc->watched = $watched;
- $rc->link = $clink;
- $rc->timestamp = $time;
- $rc->numberofWatchingusers = $baseRC->numberofWatchingusers;
-
- # Make "cur" and "diff" links. Do not use link(), it is too slow if
- # called too many times (50% of CPU time on RecentChanges!).
- $thisOldid = $rc->mAttribs['rc_this_oldid'];
- $lastOldid = $rc->mAttribs['rc_last_oldid'];
-
- $querycur = $curIdEq + array( 'diff' => '0', 'oldid' => $thisOldid );
- $querydiff = $curIdEq + array( 'diff' => $thisOldid, 'oldid' => $lastOldid );
-
- if ( !$showdifflinks ) {
- $curLink = $this->message['cur'];
- $diffLink = $this->message['diff'];
- } elseif ( in_array( $type, array( RC_NEW, RC_LOG, RC_MOVE, RC_MOVE_OVER_REDIRECT ) ) ) {
- if ( $type != RC_NEW ) {
- $curLink = $this->message['cur'];
- } else {
- $curUrl = htmlspecialchars( $rc->getTitle()->getLinkURL( $querycur ) );
- $curLink = "<a href=\"$curUrl\" tabindex=\"{$baseRC->counter}\">{$this->message['cur']}</a>";
- }
- $diffLink = $this->message['diff'];
- } else {
- $diffUrl = htmlspecialchars( $rc->getTitle()->getLinkURL( $querydiff ) );
- $curUrl = htmlspecialchars( $rc->getTitle()->getLinkURL( $querycur ) );
- $diffLink = "<a href=\"$diffUrl\" tabindex=\"{$baseRC->counter}\">{$this->message['diff']}</a>";
- $curLink = "<a href=\"$curUrl\" tabindex=\"{$baseRC->counter}\">{$this->message['cur']}</a>";
- }
+ return $ret;
+ }
- # Make "last" link
- if ( !$showdifflinks || !$lastOldid ) {
- $lastLink = $this->message['last'];
- } elseif ( in_array( $type, array( RC_LOG, RC_MOVE, RC_MOVE_OVER_REDIRECT ) ) ) {
- $lastLink = $this->message['last'];
- } else {
- $lastLink = Linker::linkKnown( $rc->getTitle(), $this->message['last'],
- array(), $curIdEq + array( 'diff' => $thisOldid, 'oldid' => $lastOldid ) );
- }
+ /**
+ * Put accumulated information into the cache, for later display.
+ * Page moves go on their own line.
+ *
+ * @param RCCacheEntry $cacheEntry
+ */
+ protected function addCacheEntry( RCCacheEntry $cacheEntry ) {
+ $cacheGroupingKey = $this->makeCacheGroupingKey( $cacheEntry );
- # Make user links
- if ( $this->isDeleted( $rc, Revision::DELETED_USER ) ) {
- $rc->userlink = ' <span class="history-deleted">' . $this->msg( 'rev-deleted-user' )->escaped() . '</span>';
- } else {
- $rc->userlink = Linker::userLink( $rc->mAttribs['rc_user'], $rc->mAttribs['rc_user_text'] );
- $rc->usertalklink = Linker::userToolLinks( $rc->mAttribs['rc_user'], $rc->mAttribs['rc_user_text'] );
+ if ( !isset( $this->rc_cache[$cacheGroupingKey] ) ) {
+ $this->rc_cache[$cacheGroupingKey] = array();
}
- $rc->lastlink = $lastLink;
- $rc->curlink = $curLink;
- $rc->difflink = $diffLink;
-
- # Put accumulated information into the cache, for later display
- # Page moves go on their own line
- $title = $rc->getTitle();
- $secureName = $title->getPrefixedDBkey();
- if ( $type == RC_MOVE || $type == RC_MOVE_OVER_REDIRECT ) {
- # Use an @ character to prevent collision with page names
- $this->rc_cache['@@' . ( $this->rcMoveIndex++ )] = array( $rc );
- } else {
- # Logs are grouped by type
- if ( $type == RC_LOG ) {
- $secureName = SpecialPage::getTitleFor( 'Log', $logType )->getPrefixedDBkey();
- }
- if ( !isset( $this->rc_cache[$secureName] ) ) {
- $this->rc_cache[$secureName] = array();
- }
+ array_push( $this->rc_cache[$cacheGroupingKey], $cacheEntry );
+ }
- array_push( $this->rc_cache[$secureName], $rc );
- }
+ /**
+ * @todo use rc_source to group, if set; fallback to rc_type
+ *
+ * @param RCCacheEntry $cacheEntry
+ *
+ * @return string
+ */
+ protected function makeCacheGroupingKey( RCCacheEntry $cacheEntry ) {
+ $title = $cacheEntry->getTitle();
+ $cacheGroupingKey = $title->getPrefixedDBkey();
- wfProfileOut( __METHOD__ );
+ $type = $cacheEntry->mAttribs['rc_type'];
- return $ret;
+ if ( $type == RC_LOG ) {
+ // Group by log type
+ $cacheGroupingKey = SpecialPage::getTitleFor(
+ 'Log',
+ $cacheEntry->mAttribs['rc_log_type']
+ )->getPrefixedDBkey();
+ }
+
+ return $cacheGroupingKey;
}
/**
* Enhanced RC group
+ * @param RCCacheEntry[] $block
* @return string
*/
protected function recentChangesBlockGroup( $block ) {
- global $wgRCShowChangedSize;
-
wfProfileIn( __METHOD__ );
# Add the namespace and title of the block as part of the class
@@ -203,7 +170,7 @@ class EnhancedChangesList extends ChangesList {
. $block[0]->mAttribs['rc_log_type'] );
} else {
$classes[] = Sanitizer::escapeClass( 'mw-changeslist-ns'
- . $block[0]->mAttribs['rc_namespace'] . '-' . $block[0]->mAttribs['rc_title'] );
+ . $block[0]->mAttribs['rc_namespace'] . '-' . $block[0]->mAttribs['rc_title'] );
}
$classes[] = $block[0]->watched && $block[0]->mAttribs['rc_timestamp'] >= $block[0]->watched
? 'mw-changeslist-line-watched' : 'mw-changeslist-line-not-watched';
@@ -221,6 +188,8 @@ class EnhancedChangesList extends ChangesList {
# Some catalyst variables...
$namehidden = true;
$allLogs = true;
+ $oldid = '';
+ $RCShowChangedSize = $this->getConfig()->get( 'RCShowChangedSize' );
foreach ( $block as $rcObj ) {
$oldid = $rcObj->mAttribs['rc_last_oldid'];
if ( $rcObj->mAttribs['rc_type'] == RC_NEW ) {
@@ -268,7 +237,9 @@ class EnhancedChangesList extends ChangesList {
$text = $userlink;
$text .= $this->getLanguage()->getDirMark();
if ( $count > 1 ) {
- $text .= ' ' . $this->msg( 'parentheses' )->rawParams( $this->getLanguage()->formatNum( $count ) . '×' )->escaped();
+ // @todo FIXME: Hardcoded '×'. Should be a message.
+ $formattedCount = $this->getLanguage()->formatNum( $count ) . '×';
+ $text .= ' ' . $this->msg( 'parentheses' )->rawParams( $formattedCount )->escaped();
}
array_push( $users, $text );
}
@@ -278,7 +249,8 @@ class EnhancedChangesList extends ChangesList {
implode( $this->message['semicolon-separator'], $users )
)->escaped() . '</span>';
- $tl = '<span class="mw-collapsible-toggle mw-collapsible-arrow mw-enhancedchanges-arrow mw-enhancedchanges-arrow-space"></span>';
+ $tl = '<span class="mw-collapsible-toggle mw-collapsible-arrow ' .
+ 'mw-enhancedchanges-arrow mw-enhancedchanges-arrow-space"></span>';
$r .= "<td>$tl</td>";
# Main line
@@ -294,7 +266,8 @@ class EnhancedChangesList extends ChangesList {
# Article link
if ( $namehidden ) {
- $r .= ' <span class="history-deleted">' . $this->msg( 'rev-deleted-event' )->escaped() . '</span>';
+ $r .= ' <span class="history-deleted">' .
+ $this->msg( 'rev-deleted-event' )->escaped() . '</span>';
} elseif ( $allLogs ) {
$r .= $this->maybeWatchedLink( $block[0]->link, $block[0]->watched );
} else {
@@ -316,6 +289,7 @@ class EnhancedChangesList extends ChangesList {
$sinceLast = 0;
$unvisitedOldid = null;
+ /** @var $rcObj RCCacheEntry */
foreach ( $block as $rcObj ) {
// Same logic as below inside main foreach
if ( $rcObj->watched && $rcObj->mAttribs['rc_timestamp'] >= $rcObj->watched ) {
@@ -331,6 +305,8 @@ class EnhancedChangesList extends ChangesList {
# Total change link
$r .= ' ';
$logtext = '';
+ /** @var $block0 RecentChange */
+ $block0 = $block[0];
if ( !$allLogs ) {
if ( !ChangesList::userCan( $rcObj, Revision::DELETED_TEXT, $this->getUser() ) ) {
$logtext .= $nchanges[$n];
@@ -338,7 +314,7 @@ class EnhancedChangesList extends ChangesList {
$logtext .= $nchanges[$n];
} else {
$logtext .= Linker::link(
- $block[0]->getTitle(),
+ $block0->getTitle(),
$nchanges[$n],
array(),
$queryParams + array(
@@ -349,7 +325,7 @@ class EnhancedChangesList extends ChangesList {
);
if ( $sinceLast > 0 && $sinceLast < $n ) {
$logtext .= $this->message['pipe-separator'] . Linker::link(
- $block[0]->getTitle(),
+ $block0->getTitle(),
$sinceLastVisitMsg[$sinceLast],
array(),
$queryParams + array(
@@ -365,7 +341,7 @@ class EnhancedChangesList extends ChangesList {
# History
if ( $allLogs ) {
// don't show history link for logs
- } elseif ( $namehidden || !$block[0]->getTitle()->exists() ) {
+ } elseif ( $namehidden || !$block0->getTitle()->exists() ) {
$logtext .= $this->message['pipe-separator'] . $this->message['enhancedrc-history'];
} else {
$params = $queryParams;
@@ -373,7 +349,7 @@ class EnhancedChangesList extends ChangesList {
$logtext .= $this->message['pipe-separator'] .
Linker::linkKnown(
- $block[0]->getTitle(),
+ $block0->getTitle(),
$this->message['enhancedrc-history'],
array(),
$params
@@ -387,7 +363,7 @@ class EnhancedChangesList extends ChangesList {
$r .= ' <span class="mw-changeslist-separator">. .</span> ';
# Character difference (does not apply if only log items)
- if ( $wgRCShowChangedSize && !$allLogs ) {
+ if ( $RCShowChangedSize && !$allLogs ) {
$last = 0;
$first = count( $block ) - 1;
# Some events (like logs) have an "empty" size, so we need to skip those...
@@ -408,7 +384,8 @@ class EnhancedChangesList extends ChangesList {
}
$r .= $users;
- $r .= $this->numberofWatchingusers( $block[0]->numberofWatchingusers );
+ $r .= $this->numberofWatchingusers( $block0->numberofWatchingusers );
+ $r .= '</td></tr>';
# Sub-entries
foreach ( $block as $rcObj ) {
@@ -443,11 +420,11 @@ class EnhancedChangesList extends ChangesList {
} else {
$link = Linker::linkKnown(
- $rcObj->getTitle(),
- $rcObj->timestamp,
- array(),
- $params
- );
+ $rcObj->getTitle(),
+ $rcObj->timestamp,
+ array(),
+ $params
+ );
if ( $this->isDeleted( $rcObj, Revision::DELETED_TEXT ) ) {
$link = '<span class="history-deleted">' . $link . '</span> ';
}
@@ -455,12 +432,16 @@ class EnhancedChangesList extends ChangesList {
$r .= $link . '</span>';
if ( !$type == RC_LOG || $type == RC_NEW ) {
- $r .= ' ' . $this->msg( 'parentheses' )->rawParams( $rcObj->curlink . $this->message['pipe-separator'] . $rcObj->lastlink )->escaped();
+ $r .= ' ' . $this->msg( 'parentheses' )->rawParams(
+ $rcObj->curlink .
+ $this->message['pipe-separator'] .
+ $rcObj->lastlink
+ )->escaped();
}
$r .= ' <span class="mw-changeslist-separator">. .</span> ';
# Character diff
- if ( $wgRCShowChangedSize ) {
+ if ( $RCShowChangedSize ) {
$cd = $this->formatCharacterDifference( $rcObj );
if ( $cd !== '' ) {
$r .= $cd . ' <span class="mw-changeslist-separator">. .</span> ';
@@ -493,56 +474,12 @@ class EnhancedChangesList extends ChangesList {
}
/**
- * Generate HTML for an arrow or placeholder graphic
- * @param string $dir one of '', 'd', 'l', 'r'
- * @param string $alt text
- * @param string $title text
- * @return String: HTML "<img>" tag
- */
- protected function arrow( $dir, $alt = '', $title = '' ) {
- global $wgStylePath;
- $encUrl = htmlspecialchars( $wgStylePath . '/common/images/Arr_' . $dir . '.png' );
- $encAlt = htmlspecialchars( $alt );
- $encTitle = htmlspecialchars( $title );
- return "<img src=\"$encUrl\" width=\"12\" height=\"12\" alt=\"$encAlt\" title=\"$encTitle\" />";
- }
-
- /**
- * Generate HTML for a right- or left-facing arrow,
- * depending on language direction.
- * @return String: HTML "<img>" tag
- */
- protected function sideArrow() {
- $dir = $this->getLanguage()->isRTL() ? 'l' : 'r';
- return $this->arrow( $dir, '+', $this->msg( 'rc-enhanced-expand' )->text() );
- }
-
- /**
- * Generate HTML for a down-facing arrow
- * depending on language direction.
- * @return String: HTML "<img>" tag
- */
- protected function downArrow() {
- return $this->arrow( 'd', '-', $this->msg( 'rc-enhanced-hide' )->text() );
- }
-
- /**
- * Generate HTML for a spacer image
- * @return String: HTML "<img>" tag
- */
- protected function spacerArrow() {
- return $this->arrow( '', codepointToUtf8( 0xa0 ) ); // non-breaking space
- }
-
- /**
* Enhanced RC ungrouped line.
*
- * @param $rcObj RecentChange
- * @return String: a HTML formatted line (generated using $r)
+ * @param RecentChange|RCCacheEntry $rcObj
+ * @return string A HTML formatted line (generated using $r)
*/
protected function recentChangesBlockLine( $rcObj ) {
- global $wgRCShowChangedSize;
-
wfProfileIn( __METHOD__ );
$query['curid'] = $rcObj->mAttribs['rc_cur_id'];
@@ -551,10 +488,10 @@ class EnhancedChangesList extends ChangesList {
$classes = array( 'mw-enhanced-rc' );
if ( $logType ) {
# Log entry
-+ $classes[] = Sanitizer::escapeClass( 'mw-changeslist-log-' . $logType );
+ $classes[] = Sanitizer::escapeClass( 'mw-changeslist-log-' . $logType );
} else {
$classes[] = Sanitizer::escapeClass( 'mw-changeslist-ns' .
- $rcObj->mAttribs['rc_namespace'] . '-' . $rcObj->mAttribs['rc_title'] );
+ $rcObj->mAttribs['rc_namespace'] . '-' . $rcObj->mAttribs['rc_title'] );
}
$classes[] = $rcObj->watched && $rcObj->mAttribs['rc_timestamp'] >= $rcObj->watched
? 'mw-changeslist-line-watched' : 'mw-changeslist-line-not-watched';
@@ -563,39 +500,37 @@ class EnhancedChangesList extends ChangesList {
$r .= '<td class="mw-enhanced-rc"><span class="mw-enhancedchanges-arrow-space"></span>';
# Flag and Timestamp
- if ( $type == RC_MOVE || $type == RC_MOVE_OVER_REDIRECT ) {
- $r .= $this->recentChangesFlags( array() ); // no flags, but need the placeholders
- } else {
- $r .= $this->recentChangesFlags( array(
- 'newpage' => $type == RC_NEW,
- 'minor' => $rcObj->mAttribs['rc_minor'],
- 'unpatrolled' => $rcObj->unpatrolled,
- 'bot' => $rcObj->mAttribs['rc_bot'],
- ) );
- }
+ $r .= $this->recentChangesFlags( array(
+ 'newpage' => $type == RC_NEW,
+ 'minor' => $rcObj->mAttribs['rc_minor'],
+ 'unpatrolled' => $rcObj->unpatrolled,
+ 'bot' => $rcObj->mAttribs['rc_bot'],
+ ) );
$r .= '&#160;' . $rcObj->timestamp . '&#160;</td><td>';
# Article or log link
if ( $logType ) {
$logPage = new LogPage( $logType );
$logTitle = SpecialPage::getTitleFor( 'Log', $logType );
$logName = $logPage->getName()->escaped();
- $r .= $this->msg( 'parentheses' )->rawParams( Linker::linkKnown( $logTitle, $logName ) )->escaped();
+ $r .= $this->msg( 'parentheses' )
+ ->rawParams( Linker::linkKnown( $logTitle, $logName ) )->escaped();
} else {
$this->insertArticleLink( $r, $rcObj, $rcObj->unpatrolled, $rcObj->watched );
}
# Diff and hist links
if ( $type != RC_LOG ) {
$query['action'] = 'history';
- $r .= ' ' . $this->msg( 'parentheses' )->rawParams( $rcObj->difflink . $this->message['pipe-separator'] . Linker::linkKnown(
- $rcObj->getTitle(),
- $this->message['hist'],
- array(),
- $query
- ) )->escaped();
+ $r .= ' ' . $this->msg( 'parentheses' )
+ ->rawParams( $rcObj->difflink . $this->message['pipe-separator'] . Linker::linkKnown(
+ $rcObj->getTitle(),
+ $this->message['hist'],
+ array(),
+ $query
+ ) )->escaped();
}
$r .= ' <span class="mw-changeslist-separator">. .</span> ';
# Character diff
- if ( $wgRCShowChangedSize ) {
+ if ( $this->getConfig()->get( 'RCShowChangedSize' ) ) {
$cd = $this->formatCharacterDifference( $rcObj );
if ( $cd !== '' ) {
$r .= $cd . ' <span class="mw-changeslist-separator">. .</span> ';
@@ -629,7 +564,7 @@ class EnhancedChangesList extends ChangesList {
* @return string
*/
protected function recentChangesBlock() {
- if ( count ( $this->rc_cache ) == 0 ) {
+ if ( count( $this->rc_cache ) == 0 ) {
return '';
}
@@ -655,7 +590,6 @@ class EnhancedChangesList extends ChangesList {
* @return string
*/
public function endRecentChangesList() {
- return $this->recentChangesBlock() . parent::endRecentChangesList();
+ return $this->recentChangesBlock() . '</div>';
}
-
}