<?php
+/**
+ * Classes to show various lists of changes:
+ * - watchlist
+ * - related changes
+ * - recent changes
+ *
+ * @file
+ */
/**
* @todo document
}
/**
- * Class to show various lists of changes:
- * - what links here
- * - related changes
- * - recent changes
+ * Base class for all changes lists
*/
class ChangesList {
- # Called by history lists and recent changes
public $skin;
protected $watchlist = false;
/**
* Changeslist contructor
- * @param Skin $skin
+ * @param $skin Skin
*/
public function __construct( $skin ) {
$this->skin = $skin;
* @return ChangesList derivative
*/
public static function newFromUser( &$user ) {
+ global $wgRequest;
+
$sk = $user->getSkin();
$list = null;
if( wfRunHooks( 'FetchChangesList', array( &$user, &$sk, &$list ) ) ) {
- return $user->getOption( 'usenewrc' ) ?
- new EnhancedChangesList( $sk ) : new OldChangesList( $sk );
+ $new = $wgRequest->getBool( 'enhanced', $user->getOption( 'usenewrc' ) );
+ return $new ? new EnhancedChangesList( $sk ) : new OldChangesList( $sk );
} else {
return $list;
}
/**
* Sets the list to use a <li class="watchlist-(namespace)-(page)"> tag
- * @param bool $value
+ * @param $value Boolean
*/
public function setWatchlistDivs( $value = true ) {
$this->watchlist = $value;
/**
* 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
+ * @param $new Boolean
+ * @param $minor Boolean
+ * @param $patrolled Boolean
+ * @param $nothing String to use for empty space
+ * @param $bot Boolean
+ * @return String
*/
- protected function recentChangesFlags( $new, $minor, $patrolled, $nothing = ' ', $bot = false ) {
+ protected function recentChangesFlags( $new, $minor, $patrolled, $nothing = ' ', $bot = false ) {
$f = $new ? self::flag( 'newpage' ) : $nothing;
$f .= $minor ? self::flag( 'minor' ) : $nothing;
$f .= $bot ? self::flag( 'bot' ) : $nothing;
* unpatrolled edit. By default in English it will contain "N", "m", "b",
* "!" respectively, plus it will have an appropriate title and class.
*
- * @param $key string 'newpage', 'unpatrolled', 'minor', or 'bot'
- * @return string Raw HTML
+ * @param $key String: 'newpage', 'unpatrolled', 'minor', or 'bot'
+ * @return String: Raw HTML
*/
public static function flag( $key ) {
static $messages = null;
. '</abbr>';
}
- /**
- * Some explanatory wrapper text for the given flag, to be used in a legend
- * explaining what the flags mean. For instance, "N - new page". See
- * also flag().
- *
- * @param $key string 'newpage', 'unpatrolled', 'minor', or 'bot'
- * @return string Raw HTML
- */
- private static function flagLine( $key ) {
- return wfMsgExt( "recentchanges-legend-$key", array( 'escapenoentities',
- 'replaceafter' ), self::flag( $key ) );
- }
-
- /**
- * A handy legend to tell users what the little "m", "b", and so on mean.
- *
- * @return string Raw HTML
- */
- public static function flagLegend() {
- global $wgGroupPermissions, $wgLang;
-
- $flags = array( self::flagLine( 'newpage' ),
- self::flagLine( 'minor' ) );
-
- # Don't show info on bot edits unless there's a bot group of some kind
- foreach ( $wgGroupPermissions as $rights ) {
- if ( isset( $rights['bot'] ) && $rights['bot'] ) {
- $flags[] = self::flagLine( 'bot' );
- break;
- }
- }
-
- if ( self::usePatrol() ) {
- $flags[] = self::flagLine( 'unpatrolled' );
- }
-
- return '<div class="mw-rc-label-legend">' .
- wfMsgExt( 'recentchanges-label-legend', 'parseinline',
- $wgLang->commaList( $flags ) ) . '</div>';
- }
-
/**
* Returns text for the start of the tabular part of RC
- * @return string
+ * @return String
*/
public function beginRecentChangesList() {
$this->rc_cache = array();
/**
* Show formatted char difference
- * @param int $old bytes
- * @param int $new bytes
- * @returns string
+ * @param $old Integer: bytes
+ * @param $new Integer: bytes
+ * @returns String
*/
public static function showCharacterDifference( $old, $new ) {
global $wgRCChangedSizeThreshold, $wgLang, $wgMiserMode;
/**
* Returns text for the end of RC
- * @return string
+ * @return String
*/
public function endRecentChangesList() {
if( $this->rclistOpen ) {
}
}
- protected function insertMove( &$s, $rc ) {
+ public function insertMove( &$s, $rc ) {
# Diff
$s .= '(' . $this->message['diff'] . ') (';
# Hist
);
}
- protected function insertDateHeader( &$s, $rc_timestamp ) {
+ public function insertDateHeader( &$s, $rc_timestamp ) {
global $wgLang;
# Make date header if necessary
$date = $wgLang->date( $rc_timestamp, true, true );
if( $date != $this->lastdate ) {
- if( '' != $this->lastdate ) {
+ if( $this->lastdate != '' ) {
$s .= "</ul>\n";
}
$s .= Xml::element( 'h4', null, $date ) . "\n<ul class=\"special\">";
}
}
- protected function insertLog( &$s, $title, $logtype ) {
+ public function insertLog( &$s, $title, $logtype ) {
$logname = LogPage::logName( $logtype );
$s .= '(' . $this->skin->link(
$title,
) . ')';
}
- protected function insertDiffHist( &$s, &$rc, $unpatrolled ) {
+ public function insertDiffHist( &$s, &$rc, $unpatrolled ) {
# Diff link
if( $rc->mAttribs['rc_type'] == RC_NEW || $rc->mAttribs['rc_type'] == RC_LOG ) {
$diffLink = $this->message['diff'];
array( 'known', 'noclasses' )
);
}
- $s .= '('.$diffLink.') (';
+ $s .= '(' . $diffLink . $this->message['pipe-separator'];
# History link
$s .= $this->skin->link(
$rc->getTitle(),
$s .= ') . . ';
}
- protected function insertArticleLink( &$s, &$rc, $unpatrolled, $watched ) {
+ public function insertArticleLink( &$s, &$rc, $unpatrolled, $watched ) {
global $wgContLang;
# 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
$s .= " $articlelink";
}
- protected function insertTimestamp( &$s, $rc ) {
+ public function insertTimestamp( &$s, $rc ) {
global $wgLang;
$s .= $this->message['semicolon-separator'] .
$wgLang->time( $rc->mAttribs['rc_timestamp'], true, true ) . ' . . ';
}
/** insert a formatted action */
- protected function insertAction( &$s, &$rc ) {
+ public function insertAction( &$s, &$rc ) {
if( $rc->mAttribs['rc_type'] == RC_LOG ) {
if( $this->isDeleted( $rc, LogPage::DELETED_ACTION ) ) {
$s .= ' <span class="history-deleted">' . wfMsgHtml( 'rev-deleted-event' ) . '</span>';
}
/** insert a formatted comment */
- protected function insertComment( &$s, &$rc ) {
+ public function insertComment( &$s, &$rc ) {
if( $rc->mAttribs['rc_type'] != RC_MOVE && $rc->mAttribs['rc_type'] != RC_MOVE_OVER_REDIRECT ) {
if( $this->isDeleted( $rc, Revision::DELETED_COMMENT ) ) {
$s .= ' <span class="history-deleted">' . wfMsgHtml( 'rev-deleted-comment' ) . '</span>';
/**
* Check whether to enable recent changes patrol features
- * @return bool
+ * @return Boolean
*/
public static function usePatrol() {
global $wgUser;
/**
* Determine if said field of a revision is hidden
- * @param RCCacheEntry $rc
- * @param int $field one of DELETED_* bitfield constants
- * @return bool
+ * @param $rc RCCacheEntry
+ * @param $field Integer: one of DELETED_* bitfield constants
+ * @return Boolean
*/
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
+ * @param $rc RCCacheEntry
+ * @param $field Integer
+ * @return Boolean
*/
public static function userCan( $rc, $field ) {
if( $rc->mAttribs['rc_type'] == RC_LOG ) {
*/
class EnhancedChangesList extends ChangesList {
/**
- * Add the JavaScript file for enhanced changeslist
- * @ return string
- */
+ * Add the JavaScript file for enhanced changeslist
+ * @return String
+ */
public function beginRecentChangesList() {
- global $wgStylePath, $wgStyleVersion;
+ global $wgOut;
$this->rc_cache = array();
$this->rcMoveIndex = 0;
$this->rcCacheIndex = 0;
$this->lastdate = '';
$this->rclistOpen = false;
- $script = Html::linkedScript( $wgStylePath . "/common/enhancedchanges.js?$wgStyleVersion" );
- return $script;
+ $wgOut->addModules( 'mediawiki.legacy.enhancedchanges' );
+ return '';
}
/**
* Format a line for enhanced recentchange (aka with javascript and block of lines).
# Process current cache
$ret = $this->recentChangesBlock();
$this->rc_cache = array();
- $ret .= Xml::element( 'h4', null, $date );
+ $ret .= Xml::element( 'h4', null, $date ) . "\n";
$this->lastdate = $date;
}
wfProfileIn( __METHOD__ );
- $r = '<table class="mw-enhanced-rc"><tr>';
+ # Add the namespace and title of the block as part of the class
+ if ( $block[0]->mAttribs['rc_log_type'] ) {
+ # Log entry
+ $classes = 'mw-enhanced-rc ' . Sanitizer::escapeClass( 'mw-changeslist-log-' . $block[0]->mAttribs['rc_log_type'] . '-' . $block[0]->mAttribs['rc_title'] );
+ } else {
+ $classes = 'mw-enhanced-rc ' . Sanitizer::escapeClass( 'mw-changeslist-ns' . $block[0]->mAttribs['rc_namespace'] . '-' . $block[0]->mAttribs['rc_title'] );
+ }
+ $r = Html::openElement( 'table', array( 'class' => $classes ) ) .
+ Html::openElement( 'tr' );
# Collate list of users
$userlinks = array();
$tl = "<span id='mw-rc-openarrow-$jsid' class='mw-changeslist-expanded' style='visibility:hidden'><a href='#' $toggleLink title='$expandTitle'>" . $this->sideArrow() . "</a></span>";
$tl .= "<span id='mw-rc-closearrow-$jsid' class='mw-changeslist-hidden' style='display:none'><a href='#' $toggleLink title='$closeTitle'>" . $this->downArrow() . "</a></span>";
- $r .= '<td class="mw-enhanced-rc">'.$tl.' ';
+ $r .= '<td class="mw-enhanced-rc">'.$tl.' ';
# Main line
- $r .= $this->recentChangesFlags( $isnew, false, $unpatrolled, ' ', $bot );
+ $r .= $this->recentChangesFlags( $isnew, false, $unpatrolled, ' ', $bot );
# Timestamp
- $r .= ' '.$block[0]->timestamp.' </td><td style="padding:0px;">';
+ $r .= ' '.$block[0]->timestamp.' </td><td style="padding:0px;">';
# Article link
if( $namehidden ) {
#$r .= '<tr><td valign="top">'.$this->spacerArrow();
$r .= '<tr><td style="vertical-align:top;font-family:monospace; padding:0px;">';
$r .= $this->spacerIndent() . $this->spacerIndent();
- $r .= $this->recentChangesFlags( $rc_new, $rc_minor, $rcObj->unpatrolled, ' ', $rc_bot );
- $r .= ' </td><td style="vertical-align:top; padding:0px;"><span style="font-family:monospace">';
+ $r .= $this->recentChangesFlags( $rc_new, $rc_minor, $rcObj->unpatrolled, ' ', $rc_bot );
+ $r .= ' </td><td style="vertical-align:top; padding:0px;"><span style="font-family:monospace">';
$params = $queryParams;
/**
* 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
+ * @param $dir String: one of '', 'd', 'l', 'r'
+ * @param $alt String: text
+ * @param $title String: text
+ * @return String: HTML <img> tag
*/
protected function arrow( $dir, $alt='', $title='' ) {
global $wgStylePath;
/**
* Generate HTML for a right- or left-facing arrow,
* depending on language direction.
- * @return string HTML <img> tag
+ * @return String: HTML <img> tag
*/
protected function sideArrow() {
global $wgContLang;
/**
* Generate HTML for a down-facing arrow
* depending on language direction.
- * @return string HTML <img> tag
+ * @return String: HTML <img> tag
*/
protected function downArrow() {
return $this->arrow( 'd', '-', wfMsg( 'rc-enhanced-hide' ) );
/**
* Generate HTML for a spacer image
- * @return string HTML <img> tag
+ * @return String: HTML <img> tag
*/
protected function spacerArrow() {
return $this->arrow( '', codepointToUtf8( 0xa0 ) ); // non-breaking space
/**
* Add a set of spaces
- * @return string HTML <td> tag
+ * @return String: HTML <td> tag
*/
protected function spacerIndent() {
- return ' ';
+ return '     ';
}
/**
* Enhanced RC ungrouped line.
- * @return string a HTML formated line (generated using $r)
+ * @return String: a HTML formated line (generated using $r)
*/
protected function recentChangesBlockLine( $rcObj ) {
global $wgRCShowChangedSize;
# 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 variables.
- $classes = array(); // TODO implement
+ // TODO implement
extract( $rcObj->mAttribs );
$query['curid'] = $rc_cur_id;
- $r = '<table class="mw-enhanced-rc"><tr>';
- $r .= '<td class="mw-enhanced-rc">' . $this->spacerArrow() . ' ';
+ if( $rc_log_type ) {
+ # Log entry
+ $classes = 'mw-enhanced-rc ' . Sanitizer::escapeClass( 'mw-changeslist-log-' . $rc_log_type . '-' . $rcObj->mAttribs['rc_title'] );
+ } else {
+ $classes = 'mw-enhanced-rc ' . Sanitizer::escapeClass( 'mw-changeslist-ns' . $rcObj->mAttribs['rc_namespace'] . '-' . $rcObj->mAttribs['rc_title'] );
+ }
+ $r = Html::openElement( 'table', array( 'class' => $classes ) ) .
+ Html::openElement( 'tr' );
+
+ $r .= '<td class="mw-enhanced-rc">' . $this->spacerArrow() . ' ';
# Flag and Timestamp
if( $rc_type == RC_MOVE || $rc_type == RC_MOVE_OVER_REDIRECT ) {
- $r .= ' '; // 4 flags -> 4 spaces
+ $r .= '    '; // 4 flags -> 4 spaces
} else {
- $r .= $this->recentChangesFlags( $rc_type == RC_NEW, $rc_minor, $rcObj->unpatrolled, ' ', $rc_bot );
+ $r .= $this->recentChangesFlags( $rc_type == RC_NEW, $rc_minor, $rcObj->unpatrolled, ' ', $rc_bot );
}
- $r .= ' '.$rcObj->timestamp.' </td><td style="padding:0px;">';
+ $r .= ' '.$rcObj->timestamp.' </td><td style="padding:0px;">';
# Article or log link
if( $rc_log_type ) {
$logtitle = Title::newFromText( "Log/$rc_log_type", NS_SPECIAL );