Open main menu

Extension:Unmerged Recent Changes

MediaWiki extensions manual
OOjs UI icon advanced.svg
Unmerged Recent Changes
Release status: beta
Implementation Special page
Description A variant of Special:Recentchanges where the feeds do not merge adjacent edits by the same user.
Author(s) Kilian Evang
Latest version 1.1 (2010-08-12)
MediaWiki 1.16.0
License GPL
Download No link
Translate the Unmerged Recent Changes extension if it is available at translatewiki.net
Check usage and version matrix.

The Unmerged Recent Changes extension provides a special page that is identical to Special:Recentchanges, except that the associated feeds do not merge adjacent changes by the same user. This is useful when one wants to follow all changes in a Wiki in a detailed fashion in a feed reader.

Contents

InstallationEdit

In your Mediawiki installation, create the folder extensions/UnmergedRecentChanges and put the four files below there. Then add the following line to you LocalSettings.php:

require_once("$IP/extensions/UnmergedRecentChanges/UnmergedRecentChanges.php");

FilesEdit

UnmergedChangesFeed.phpEdit

<?php

class UnmergedChangesFeed extends ChangesFeed {

	public function execute( $feed, $rows, $lastmod, $opts ) {
		global $messageMemc, $wgFeedCacheTimeout;
		global $wgSitename, $wgLang;

		if ( !FeedUtils::checkFeedOutput( $this->format ) ) {
			return;
		}

		$timekey = wfMemcKey( $this->type, $this->format, 'timestamp' );
		$optionsHash = md5( serialize( $opts->getAllValues() ) );
		$key = wfMemcKey( $this->type, $this->format, $wgLang->getCode(), $optionsHash );

		FeedUtils::checkPurge($timekey, $key);

		/*
		* Bumping around loading up diffs can be pretty slow, so where
		* possible we want to cache the feed output so the next visitor
		* gets it quick too.
		*/
		$cachedFeed = $this->loadFromCache( $lastmod, $timekey, $key );
		if( is_string( $cachedFeed ) ) {
			wfDebug( "URC: Outputting cached feed\n" );
			$feed->httpHeaders();
			echo $cachedFeed;
		} else {
			wfDebug( "URC: rendering new feed and caching it\n" );
			ob_start();
			self::generateFeed( $rows, $feed );
			$cachedFeed = ob_get_contents();
			ob_end_flush();
			$this->saveToCache( $cachedFeed, $timekey, $key );
		}
		return true;
	}

	/**
	 * Generate the feed items given a row from the database.
	 * @param $rows DatabaseBase resource with recentchanges rows
	 * @param $feed Feed object
	 */
	public static function generateFeed( $rows, &$feed ) {
		wfProfileIn( __METHOD__ );

		$feed->outHeader();

		# Do not merge adjacent edits by one user
		$sorted = $rows;

		foreach( $sorted as $obj ) {
			$title = Title::makeTitle( $obj->rc_namespace, $obj->rc_title );
			$talkpage = $title->getTalkPage();
			$item = new FeedItem(
				$title->getPrefixedText(),
				FeedUtils::formatDiff( $obj ),
				$title->getFullURL( 'diff=' . $obj->rc_this_oldid . '&oldid=prev' ),
				$obj->rc_timestamp,
				($obj->rc_deleted & Revision::DELETED_USER) ? wfMsgHtml('rev-deleted-user') : $obj->rc_user_text,
				$talkpage->getFullURL()
				);
			$feed->outItem( $item );
		}
		$feed->outFooter();
		wfProfileOut( __METHOD__ );
	}

}

UnmergedRecentChanges.body.phpEdit

<?php

/**
 * Exactly like Special:Recentchanges, only the feeds does not merge adjacent
 * edits by one user.
 */
class UnmergedRecentChanges extends SpecialRecentChanges {

	public function __construct() {
  		SpecialPage::SpecialPage( 'UnmergedRecentChanges' );
		$this->includable( true );
	}

	/**
	 * Return an array with a ChangesFeed object and ChannelFeed object
	 *
	 * @return array
	 */
	public function getFeedObject( $feedFormat ){
		$feed = new UnmergedChangesFeed( $feedFormat, 'urcfeed' );
		$feedObj = $feed->getFeedObject(
			wfMsgForContent( 'unmergedrecentchanges' ),
			wfMsgForContent( 'unmergedrecentchanges-feed-description' )
		);
		return array( $feed, $feedObj );
	}

}

UnmergedRecentChanges.i18n.phpEdit

<?php
$messages = array(
        'en' => array( 
                'unmergedrecentchanges' => 'Unmerged Recent Changes',
		'unmergedrecentchanges-feed-description' => 'Track the most recent changes to the wiki in this feed in detail.'
        ),
        'de' => array( 
                'unmergedrecentchanges' => 'Letzte Änderungen (nicht verschmolzen)',
		'unmergedrecentchanges-feed-description' => 'Verfolge mit diesem Feed die letzten Änderungen in {{SITENAME}} im Detail.'
        )
);

UnmergedRecentChanges.phpEdit

<?php
# Not a valid entry point, skip unless MEDIAWIKI is defined
if (!defined('MEDIAWIKI')) {
        echo <<<EOT
To install my extension, put the following line in LocalSettings.php:
require_once( "$IP/extensions/UnmergedRecentChanges/UnmergedRecentChanges.php" );
EOT;
        exit( 1 );
}

$wgExtensionCredits['specialpage'][] = array(
        'name' => 'UnmergedRecentChanges',
        'author' => 'Kilian Evang',
        'description' => 'Exactly like Special:RecentChanges, only the feed does not merge adjacent edits by one user',
	'url' => 'http://www.mediawiki.org/wiki/Extension:Unmerged_Recent_Changes'
);

$dir = dirname(__FILE__) . '/';

$wgAutoloadClasses['UnmergedChangesFeed'] = $dir . 'UnmergedChangesFeed.php';
$wgAutoloadClasses['UnmergedRecentChanges'] = $dir . 'UnmergedRecentChanges.body.php';
$wgExtensionMessagesFiles['UnmergedRecentChanges'] = $dir . 'UnmergedRecentChanges.i18n.php';
$wgSpecialPages['UnmergedRecentChanges'] = 'UnmergedRecentChanges';
$wgHooks['LanguageGetSpecialPageAliases'][] = 'unmergedRecentChangesLocalizedSpecialPageName';

function unmergedRecentChangesLocalizedSpecialPageName(&$specialPageArray, $code) {
	# The localized title of the special page is among the messages of the
	# extension:
	wfLoadExtensionMessages('UnmergedRecentChanges');
	$text = wfMsg('unmergedrecentchanges');

	if ($text) {
		# Convert from title to DBKey and put it into the alias array:
		$title = Title::newFromText($text);
		$specialPageArray['UnmergedRecentChanges'][] = $title->getDBKey();
	}

	return true;
}

?>