Extension:TransformChanges.php

From Organic Design wiki
Revision as of 12:31, 23 March 2009 by Nad (talk | contribs) (1.1.5 - working better now)

<? /**

* TransformChanges extension - Makes recent-changes and watchlists render in nice columns for easier reading
* Template:Php
Info.svg These are the MediaWiki extensions we're using and/or developing. Please refer to the information on the mediawiki.org wiki for installation and usage details. Extensions here which have no corresponding mediawiki article are either not ready for use or have been superseded. You can also browse our extension code in our local Subversion repository or our GitHub mirror.
* 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.5, 2009-03-24' );

$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 );

  1. Disable enhanced recent changes

$wgExtensionFunctions[] = 'wfSetupTransformChanges'; function wfSetupTransformChanges() { global $wgUser; $wgUser->setOption( 'usenewrc', false ); }

  1. A hack for 1.12+ to ensure the SpecialPageExecuteAfterPage hook gets called

$wgHooks['ChangesListInsertArticleLink'][] = 'wfRunSpecialPageExecuteAfterPageHook'; function wfRunSpecialPageExecuteAfterPageHook() {

# Bail if already done 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';

      $rows = preg_replace_callback( '|<li\\s*(.*?)>(.+?)|s', 'wfTransformChangesLI', $match[1] );

      return $rows; }

      function wfTransformChangesLI( $match ) { global $wgTransformChangesRow, $wgSimpleSecurity; $wgTransformChangesRow = $wgTransformChangesRow == 'even' ? 'odd' : 'even'; $talk = ; list( , $date, $text ) = $match; #$cols = array('time', 'title', 'user', 'talk', 'info', 'comment', 'diff');

      # OrganicDesign has different columns and order $cols = array( 'time', 'diff', 'title', 'comment', 'user', 'info' );

      $ncols = count( $cols ); $row = ;

      $error = 'Error: match failed!';

      if ( $date ) {

      $row = "$date\n";

      $wgTransformChangesRow = 'even';

      # OrganicDesign's table header

      static $head = "TimeActionsItem changedDescription of changeChanged byDetails";

      $row .= $head; $head = ; }

      $row .= ""; if (preg_match( '%^(.*?);( |\\s+)(\\d+:\\d+)(.+?)(<a.+?</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>).+?(\\(.+?</a>\\))|', $user, $m ) ) { list( , $user, $talk ) = $m; if ( ereg( '@', $user ) || !eregi( '[a-z]',$user ) ) { $talk = ; $user = strtolower( $user ); } } # Only show row if ok by SimpleSecurity extension $allowed = true; if ( preg_match('|title="(.+?)"|', $title, $m ) && is_object( $wgSimpleSecurity ) ) { global $wgUser; $t = Title::newFromText( $m[1] ); $allowed = version_compare( SIMPLESECURITY_VERSION, '4.0.0' ) < 0 ? $wgSimpleSecurity->validateTitle( 'view', $t ) : $wgSimpleSecurity->userCanReadTitle( $wgUser, $t, $error ); } # OrganicDesign has an edit link instead of talk and hist $talk = preg_replace( '| \\|.+</a>|', , $talk ); $diff = preg_replace( '|curid=[0-9]+&(amp;)?action=history|', 'action=edit', $diff ); $diff = preg_replace( '|>hist<|', '>edit<', $diff ); $user .= " $talk"; if ( $allowed ) foreach ( $cols as $col ) { $val = isset($$col) ? $$col : ; $row .= "$val";

      } } else $row = $error;

      $row .= "\n"; return $row; }
      1. 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] ); }