<?
# Extension:TransformChanges
# - See http://www.mediawiki.org/Extension:TransformChanges for installation and usage details
# - Licenced under LGPL (http://www.gnu.org/copyleft/lesser.html)
if (!defined('MEDIAWIKI')) die('Not an entry point.');
define('TRANSFORMCHANGES_VERSION','1.0.7, 2007-09-08');
$wgExtensionCredits['other'][] = array(
'name' => 'TransformChanges',
'author' => '[http://www.organicdesign.co.nz/nad User:Nad]',
'description' => 'Makes recent-changes and watchlists render in nice columns for easier reading.',
'url' => 'http://www.organicdesign.co.nz/Extension:TransformChanges',
'version' => TRANSFORMCHANGES_VERSION
);
## Returns the position of the $n-th $c token (string) in $haystack (= position at the end of the token)
function strposn($haystack, $c, $n) {
$a = explode($c, $haystack, $n+1);
if($n <= 0 || count($a) <= $n)
return false;
return strlen($haystack) - strlen($a[$n]);
}
# Disable enhanced recent changes
$wgExtensionFunctions[] = 'wfSetupTransformChanges';
function wfSetupTransformChanges() {
global $wgUser;
$wgUser->setOption('usenewrc',false);
}
$wgHooks['SpecialPageExecuteAfterPage'][] = 'wfTransformChanges';
function wfTransformChanges() {
global $wgOut;
$title = $wgOut->getPageTitle();
if ($title != wfMsgForContent('recentchanges') && $title != wfMsgForContent('watchlist')) return true;
$text =& $wgOut->mBodytext;
$text = preg_replace('|(</ul>\\s*)?<h4>(.+?)</h4>\\s*(<ul class="special">)<li>|s','$3<li $2>',$text);
## Edits by Fish1203
## (http://www.mediawiki.org/wiki/User:Fish1203)
## solving the PHP preg_replace_callback() pcre.backtrack_limit problem
## splitting in days
$parts = explode('<ul class="special">',$text);
$first = 1;
$nbedits = 50;
$text = $parts[0] . "<table class=\"changes\">";
foreach($parts as $part) {
if ($first == 1) { ## skipping first part (= Special:RecentChanges "header")
$first = 0;
}
else {
$nbsubparts = (substr_count($part,"</li>") - 1); ## how many edits for this day ?
## if more than $nbedits edits for this day
if ($nbsubparts > $nbedits) {
$divide = intval(abs($nbsubparts/$nbedits));
## splits each day in parts containing $nbedits edits (max.)
$start = 0;
$parts2 = array();
for($lp=0; $lp<$divide; $lp++) {
$parts2[$lp] = substr($part, $start, (strposn($part,"</li>",($lp+1)*$nbedits))-$start );
$start = (strposn($part,"</li>",($lp+1)*$nbedits));
}
$parts2[$divide] = substr($part, $start, strlen($part)); ## last part for the day
foreach($parts2 as $part2) {
$part2 = '<ul class="special">' . $part2 . '</ul>';
$text .= preg_replace_callback('|<ul class="special">(.+?)</ul>|s','wfTransformChangesUL',$part2);
}
}
else {
$part = '<ul class="special">' . $part . '</ul>';
$text .= preg_replace_callback('|<ul class="special">(.+?)</ul>|s','wfTransformChangesUL',$part);
}
}
}
## there may be one last </ul> tag remaining...
## just remove it... :-)
$text = str_replace("</ul>","",$text);
$text .= "</table>";
return true;
}
function wfTransformChangesUL($match) {
global $wgTransformChangesRow;
$wgTransformChangesRow = 'odd'; ## was originally $wgTransformChangesRow = 0
$rows = preg_replace_callback('|<li\\s*(.*?)>(.+?)</li>|s','wfTransformChangesLI',$match[1]);
return $rows;
}
function wfTransformChangesLI($match) {
global $wgTransformChangesRow,$wgSimpleSecurity;
$wgTransformChangesRow = $wgTransformChangesRow == 'even' ? 'odd' : 'even';
list(,$date,$text) = $match;
$cols = array('time','title','user','talk','info','comment','diff');
$ncols = count($cols);
$row = '';
$error = '<td colspan="$ncols"><font color="red"><b>Error: match failed!</b></font></td>';
if ($date) {
$row = "<tr><td class=\"heading\" colspan=\"$ncols\">$date</td></tr>\n";
$wgTransformChangesRow = 'even';
}
$row .= "<tr class=\"$wgTransformChangesRow\">";
if (preg_match('|^(.*?); (\\d+:\\d+)(.+?)(<a.+?\\))\\s*(.*?)$|',$text,$m)) {
list(,$diff,$time,$bytes,$user,$comment) = $m;
if (preg_match('|^(.+\\)).*?\\. \\.\\s*(.*?)\\s*(<a.+)$|',$diff,$m)) list(,$diff,$info,$title) = $m; else $info = $title = '';
if (preg_match('|(\\(.+?\\))|',$bytes,$m)) $info .= "<small>$m[1]</small>";
if (preg_match('|(<a.+?</a>).+?(\\(.+?\\))|',$user,$m)) {
# Remove talk for email or IP users and make user lowercase
list(,$user,$talk) = $m;
if (ereg('@',$user) || !eregi('[a-z]',$user)) { $talk = ''; $user = strtolower($user); }
}
if (preg_match('|\\((.+)\\)|',$comment,$m)) $comment = $m[1];
$allowed = true;
if (preg_match('|title="(.+?)"|',$title,$m) && is_object($wgSimpleSecurity)) {
# Only show row if ok by SimpleSecurity extension
$t = Title::newFromText($m[1]);
$allowed = $wgSimpleSecurity->validateTitle('view',$t);
}
if ($allowed) foreach ($cols as $col) $row .= "<td class=\"$col\">{$$col}</td>";
} else $row = $error;
$row .= "</tr>\n";
return $row;
}
?>