Difference between revisions of "Extension:TransformChanges.php"
m |
(almost working for 1.12+ but not quite) |
||
Line 1: | Line 1: | ||
<? | <? | ||
− | + | /** | |
− | + | * TransformChanges extension - Makes recent-changes and watchlists render in nice columns for easier reading | |
− | + | * {{php}}{{Category:Extensions|TransformChanges}} | |
+ | * See http://www.mediawiki.org/wiki/Extension:TransformChanges for installation and usage details | ||
+ | * | ||
+ | * @package MediaWiki | ||
+ | * @subpackage Extensions | ||
+ | * @author Aran Dunkley [http://www.organicdesign.co.nz/nad User:Nad] | ||
+ | * @copyright © 2007 Aran Dunkley | ||
+ | * @licence GNU General Public Licence 2.0 or later | ||
+ | */ | ||
if (!defined('MEDIAWIKI')) die('Not an entry point.'); | if (!defined('MEDIAWIKI')) die('Not an entry point.'); | ||
− | define('TRANSFORMCHANGES_VERSION','1.0 | + | define('TRANSFORMCHANGES_VERSION', '1.1.0, 2009-01-13'); |
$wgExtensionCredits['other'][] = array( | $wgExtensionCredits['other'][] = array( | ||
− | + | 'name' => 'TransformChanges', | |
− | + | 'author' => '[http://www.organicdesign.co.nz/nad User:Nad], [http://www.mediawiki.org/wikiUser:Fish1203 User:Fish1203]', | |
− | + | 'description' => 'Makes recent-changes and watchlists render in nice columns for easier reading.', | |
− | + | 'url' => 'http://www.organicdesign.co.nz/Extension:TransformChanges', | |
− | + | 'version' => TRANSFORMCHANGES_VERSION | |
); | ); | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
# Disable enhanced recent changes | # Disable enhanced recent changes | ||
$wgExtensionFunctions[] = 'wfSetupTransformChanges'; | $wgExtensionFunctions[] = 'wfSetupTransformChanges'; | ||
function wfSetupTransformChanges() { | function wfSetupTransformChanges() { | ||
− | + | global $wgUser; | |
− | + | $wgUser->setOption('usenewrc', false); | |
+ | } | ||
+ | |||
+ | # A hack for 1.12+ to ensure the SpecialPageExecuteAfterPage hook gets called | ||
+ | $wgHooks['ChangesListInsertArticleLink'][] = 'wfRunSpecialPageExecuteAfterPageHook'; | ||
+ | function wfRunSpecialPageExecuteAfterPageHook() { | ||
+ | static $done = 0; | ||
+ | if ($done++) return true; | ||
+ | |||
+ | # Create a replica of the OutputPage class which calls the SpecialPageExecuteAfterPage after recentchanges rendered | ||
+ | class OutputPage2 extends OutputPage { | ||
+ | function addHTML($text) { | ||
+ | parent::addHTML($text); | ||
+ | if (ereg('^<h4>', $text)) wfRunHooks('SpecialPageExecuteAfterPage', array()); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | # Replace the global $wgOut object with an identical instance of the new OutputPage2 class | ||
+ | global $wgOut; | ||
+ | $oldOut = $wgOut; | ||
+ | $wgOut = new OutputPage2(); | ||
+ | foreach (array_keys(get_class_vars('OutputPage')) as $k) $wgOut->$k = $oldOut->$k; | ||
+ | |||
+ | return true; | ||
} | } | ||
$wgHooks['SpecialPageExecuteAfterPage'][] = 'wfTransformChanges'; | $wgHooks['SpecialPageExecuteAfterPage'][] = 'wfTransformChanges'; | ||
function 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) { | ||
+ | # skipping first part (= Special:RecentChanges "header") | ||
+ | if ($first == 1) $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)); | |
− | + | } | |
− | + | ||
− | + | # last part for the day | |
− | + | $parts2[$divide] = substr($part, $start, strlen($part)); | |
− | |||
− | |||
− | + | 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) { | 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) { | 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>"; | |
− | + | ||
− | + | # Remove talk for email or IP users and make user lowercase | |
− | + | if (preg_match('|(<a.+?</a>).+?(\\(.+?\\))|', $user, $m)) { | |
− | + | list(, $user, $talk) = $m; | |
− | + | if (ereg('@', $user) || !eregi('[a-z]',$user)) { $talk = ''; $user = strtolower($user); } | |
− | + | } | |
− | + | if (preg_match('|\\((.+)\\)|', $comment, $m)) $comment = $m[1]; | |
− | + | ||
− | + | # Only show row if ok by SimpleSecurity extension | |
− | + | $allowed = true; | |
− | + | if (preg_match('|title="(.+?)"|', $title, $m) && is_object($wgSimpleSecurity)) { | |
− | + | $t = Title::newFromText($m[1]); | |
− | + | $allowed = version_compare(SIMPLESECURITY_VERSION, '4.0.0') < 0 | |
− | + | ? $wgSimpleSecurity->validateTitle('view', $t) | |
− | + | : $t->userCan($action); | |
− | + | } | |
+ | if ($allowed) foreach ($cols as $col) { | ||
+ | $val = isset($$col) ? $$col : ''; | ||
+ | $row .= "<td class=\"$col\">$val</td>"; | ||
+ | } | ||
+ | } else $row = $error; | ||
+ | $row .= "</tr>\n"; | ||
+ | return $row; | ||
+ | } | ||
+ | |||
+ | # 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]); | ||
} | } |
Revision as of 06:39, 13 January 2009
<? /**
* TransformChanges extension - Makes recent-changes and watchlists render in nice columns for easier reading * Template:Php
* See http://www.mediawiki.org/wiki/Extension:TransformChanges for installation and usage details * * @package MediaWiki * @subpackage Extensions * @author Aran Dunkley User:Nad * @copyright © 2007 Aran Dunkley * @licence GNU General Public Licence 2.0 or later */
if (!defined('MEDIAWIKI')) die('Not an entry point.');
define('TRANSFORMCHANGES_VERSION', '1.1.0, 2009-01-13');
$wgExtensionCredits['other'][] = array( 'name' => 'TransformChanges', 'author' => 'User:Nad, User:Fish1203', 'description' => 'Makes recent-changes and watchlists render in nice columns for easier reading.', 'url' => 'http://www.organicdesign.co.nz/Extension:TransformChanges', 'version' => TRANSFORMCHANGES_VERSION );
- Disable enhanced recent changes
$wgExtensionFunctions[] = 'wfSetupTransformChanges'; function wfSetupTransformChanges() { global $wgUser; $wgUser->setOption('usenewrc', false); }
- A hack for 1.12+ to ensure the SpecialPageExecuteAfterPage hook gets called
$wgHooks['ChangesListInsertArticleLink'][] = 'wfRunSpecialPageExecuteAfterPageHook'; function wfRunSpecialPageExecuteAfterPageHook() { static $done = 0; if ($done++) return true;
# Create a replica of the OutputPage class which calls the SpecialPageExecuteAfterPage after recentchanges rendered class OutputPage2 extends OutputPage { function addHTML($text) { parent::addHTML($text);
if (ereg('^
', $text)) wfRunHooks('SpecialPageExecuteAfterPage', array());
}
}
# Replace the global $wgOut object with an identical instance of the new OutputPage2 class
global $wgOut;
$oldOut = $wgOut;
$wgOut = new OutputPage2();
foreach (array_keys(get_class_vars('OutputPage')) as $k) $wgOut->$k = $oldOut->$k;
return true;
}
$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('|(\\s*)?(.+?)
\\s*()- |s', '$3
- ', $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("", $text);
$first = 1;
$nbedits = 50;
$text = $parts[0] . "";
foreach ($parts as $part) {
# skipping first part (= Special:RecentChanges "header")
if ($first == 1) $first = 0;
else {
$nbsubparts = (substr_count($part, "")-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, "", ($lp+1)*$nbedits))-$start );
$start = (strposn($part, "", ($lp+1)*$nbedits));
}
# last part for the day
$parts2[$divide] = substr($part, $start, strlen($part));
foreach($parts2 as $part2) {
$part2 = "$part2
";
$text .= preg_replace_callback("|(.+?)
|s", 'wfTransformChangesUL', $part2);
}
}
else {
$part = "$part
";
$text .= preg_replace_callback("|(.+?)
|s", 'wfTransformChangesUL', $part);
}
}
}
# there may be one last tag remaining... just remove it... :-)
$text = str_replace("", "", $text);
$text .= "
";
return true;
}
function wfTransformChangesUL($match) {
global $wgTransformChangesRow;
$wgTransformChangesRow = 'odd'; ## was originally $wgTransformChangesRow = 0
$rows = preg_replace_callback('|<li\\s*(.*?)>(.+?)|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 = 'Error: match failed!';
if ($date) {
$row = "$date\n";
$wgTransformChangesRow = 'even';
}
$row .= "";
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 .= "$m[1]";
# Remove talk for email or IP users and make user lowercase
if (preg_match('|(<a.+?</a>).+?(\\(.+?\\))|', $user, $m)) {
list(, $user, $talk) = $m;
if (ereg('@', $user) || !eregi('[a-z]',$user)) { $talk = ; $user = strtolower($user); }
}
if (preg_match('|\\((.+)\\)|', $comment, $m)) $comment = $m[1];
# Only show row if ok by SimpleSecurity extension
$allowed = true;
if (preg_match('|title="(.+?)"|', $title, $m) && is_object($wgSimpleSecurity)) {
$t = Title::newFromText($m[1]);
$allowed = version_compare(SIMPLESECURITY_VERSION, '4.0.0') < 0
? $wgSimpleSecurity->validateTitle('view', $t)
: $t->userCan($action);
}
if ($allowed) foreach ($cols as $col) {
$val = isset($$col) ? $$col : ;
$row .= "$val";
}
} else $row = $error;
$row .= "\n";
return $row;
}
- 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]);
}
# 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("- ", $text);
$first = 1;
$nbedits = 50;
$text = $parts[0] . "";
foreach ($parts as $part) {
# skipping first part (= Special:RecentChanges "header")
if ($first == 1) $first = 0;
else {
$nbsubparts = (substr_count($part, "")-1); # how many edits for this day ?
- Returns the position of the $n-th $c token (string) in $haystack (= position at the end of the token)
# 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, "", ($lp+1)*$nbedits))-$start ); $start = (strposn($part, "", ($lp+1)*$nbedits));}
# last part for the day $parts2[$divide] = substr($part, $start, strlen($part));
foreach($parts2 as $part2) {
$part2 = "- $part2
- (.+?)
} } else {
$part = "- $part
- (.+?)
} } }
# there may be one last tag remaining... just remove it... :-) $text = str_replace("", "", $text); $text .= "return true; }
function wfTransformChangesUL($match) { global $wgTransformChangesRow; $wgTransformChangesRow = 'odd'; ## was originally $wgTransformChangesRow = 0
$rows = preg_replace_callback('|<li\\s*(.*?)>(.+?)|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 = 'Error: match failed!';if ($date) {
$row = "$date\n";$wgTransformChangesRow = 'even'; }
$row .= ""; 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 .= "$m[1]"; # Remove talk for email or IP users and make user lowercase if (preg_match('|(<a.+?</a>).+?(\\(.+?\\))|', $user, $m)) { list(, $user, $talk) = $m; if (ereg('@', $user) || !eregi('[a-z]',$user)) { $talk = ; $user = strtolower($user); } } if (preg_match('|\\((.+)\\)|', $comment, $m)) $comment = $m[1]; # Only show row if ok by SimpleSecurity extension $allowed = true; if (preg_match('|title="(.+?)"|', $title, $m) && is_object($wgSimpleSecurity)) { $t = Title::newFromText($m[1]); $allowed = version_compare(SIMPLESECURITY_VERSION, '4.0.0') < 0 ? $wgSimpleSecurity->validateTitle('view', $t) : $t->userCan($action); } if ($allowed) foreach ($cols as $col) { $val = isset($$col) ? $$col : ; $row .= "$val";} } else $row = $error;
$row .= "\n"; return $row; }