X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FSpecialRecentchanges.php;h=8ad4899d7e4ca646385285906c8b08e72b45a393;hb=2e23bc005b0ccfc8cce7047a4cba2825d8d537ab;hp=e8b763dcf63c7821f79db94c7a065858302030be;hpb=57cec6f4dc6c35840008163e4206b31a513d03d7;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/SpecialRecentchanges.php b/includes/SpecialRecentchanges.php index e8b763dcf6..8ad4899d7e 100644 --- a/includes/SpecialRecentchanges.php +++ b/includes/SpecialRecentchanges.php @@ -1,191 +1,580 @@ -checkLastModified( $s->lastmod ) ){ - # Client cache fresh and headers sent, nothing more to do. - return; - } +/** + * Constructor + */ +function wfSpecialRecentchanges( $par, $specialPage ) { + global $wgUser, $wgOut, $wgLang, $wgContLang, $wgTitle, $wgMemc, $wgDBname; + global $wgRequest, $wgSitename, $wgLanguageCode, $wgContLanguageCode; + global $wgFeedClasses, $wgUseRCPatrol; + global $wgRCShowWatchingUsers, $wgShowUpdatedMarker; + global $wgLinkCache; + $fname = 'wfSpecialRecentchanges'; - $rctext = wfMsg( "recentchangestext" ); + # Get query parameters + $feedFormat = $wgRequest->getVal( 'feed' ); + + $defaults = array( + /* int */ 'days' => $wgUser->getDefaultOption('rcdays'), + /* int */ 'limit' => $wgUser->getDefaultOption('rclimit'), + /* bool */ 'hideminor' => false, + /* bool */ 'hidebots' => true, + /* bool */ 'hideliu' => false, + /* bool */ 'hidepatrolled' => false, + /* text */ 'from' => '', + /* text */ 'namespace' => null, + /* bool */ 'invert' => false, + ); + + extract($defaults); - # The next few lines can probably be commented out now that wfMsg can get text from the DB - $sql = "SELECT cur_text FROM cur WHERE cur_namespace=4 AND cur_title='Recentchanges'"; - $res = wfQuery( $sql, DB_READ, $fname ); - if( ( $s = wfFetchObject( $res ) ) and ( $s->cur_text != "" ) ) { - $rctext = $s->cur_text; - } + + $days = $wgUser->getOption( 'rcdays' ); + if ( !$days ) { $days = $defaults['days']; } + $days = $wgRequest->getInt( 'days', $days ); + + $limit = $wgUser->getOption( 'rclimit' ); + if ( !$limit ) { $limit = $defaults['limit']; } + + # list( $limit, $offset ) = wfCheckLimits( 100, 'rclimit' ); + $limit = $wgRequest->getInt( 'limit', $limit ); + + /* order of selection: url > preferences > default */ + $hideminor = $wgRequest->getBool( 'hideminor', $wgUser->getOption( 'hideminor') ? true : $defaults['hideminor'] ); + - $wgOut->addWikiText( $rctext ); + # As a feed, use limited settings only + if( $feedFormat ) { + global $wgFeedLimit; + if( $limit > $wgFeedLimit ) { + $options['limit'] = $wgFeedLimit; + } - if ( ! $days ) { - $days = $wgUser->getOption( "rcdays" ); - if ( ! $days ) { $days = 3; } - } - $days = (int)$days; - list( $limit, $offset ) = wfCheckLimits( 100, "rclimit" ); - $now = wfTimestampNow(); - $cutoff_unixtime = time() - ( $days * 86400 ); - $cutoff_unixtime = $cutoff_unixtime - ($cutoff_unixtime % 86400); - $cutoff = wfUnix2Timestamp( $cutoff_unixtime ); - if(preg_match('/^[0-9]{14}$/', $from) and $from > $cutoff) { - $cutoff = $from; } else { - unset($from); + + $namespace = $wgRequest->getIntOrNull( 'namespace' ); + $invert = $wgRequest->getBool( 'invert', $defaults['invert'] ); + $hidebots = $wgRequest->getBool( 'hidebots', $defaults['hidebots'] ); + $hideliu = $wgRequest->getBool( 'hideliu', $defaults['hideliu'] ); + $hidepatrolled = $wgRequest->getBool( 'hidepatrolled', $defaults['hidepatrolled'] ); + $from = $wgRequest->getVal( 'from', $defaults['from'] ); + + # Get query parameters from path + if( $par ) { + $bits = preg_split( '/\s*,\s*/', trim( $par ) ); + foreach ( $bits as $bit ) { + if ( 'hidebots' == $bit ) $hidebots = 1; + if ( 'bots' == $bit ) $hidebots = 0; + if ( 'hideminor' == $bit ) $hideminor = 1; + if ( 'minor' == $bit ) $hideminor = 0; + if ( 'hideliu' == $bit ) $hideliu = 1; + if ( 'hidepatrolled' == $bit ) $hidepatrolled = 1; + + if ( is_numeric( $bit ) ) { + $limit = $bit; + } + + if ( preg_match( '/^limit=(\d+)$/', $bit, $m ) ) { + $limit = $m[1]; + } + + if ( preg_match( '/^days=(\d+)$/', $bit, $m ) ) { + $days = $m[1]; + } + } + } } - $sk = $wgUser->getSkin(); - $showhide = array( wfMsg( "show" ), wfMsg( "hide" )); + if ( $limit < 0 || $limit > 5000 ) $limit = $defaults['limit']; + + + # Database connection and caching + $dbr =& wfGetDB( DB_SLAVE ); + extract( $dbr->tableNames( 'recentchanges', 'watchlist' ) ); + - if ( ! isset( $hideminor ) ) { - $hideminor = $wgUser->getOption( "hideminor" ); - } - $hideminor = ($hideminor ? 1 : 0); - if ( $hideminor ) { - $hidem = "AND rc_minor=0"; + $cutoff_unixtime = time() - ( $days * 86400 ); + $cutoff_unixtime = $cutoff_unixtime - ($cutoff_unixtime % 86400); + $cutoff = $dbr->timestamp( $cutoff_unixtime ); + if(preg_match('/^[0-9]{14}$/', $from) and $from > wfTimestamp(TS_MW,$cutoff)) { + $cutoff = $dbr->timestamp($from); } else { - $hidem = ""; - } - - if ( !isset( $hidebots ) ) { - $hidebots = 1; - } - if( $hidebots ) { - $hidem .= " AND rc_bot=0"; - } - $hidebots = ($hidebots ? 1 : 0); - - if ( !isset( $hideliu ) ) { - $hideliu = 0; + $from = $defaults['from']; } - if ( $hideliu ) { - $hidem .= " AND rc_user=0"; + + # 10 seconds server-side caching max + $wgOut->setSquidMaxage( 10 ); + + # Get last modified date, for client caching + # Don't use this if we are using the patrol feature, patrol changes don't update the timestamp + $lastmod = $dbr->selectField( 'recentchanges', 'MAX(rc_timestamp)', false, $fname ); + if ( $feedFormat || !$wgUseRCPatrol ) { + if( $lastmod && $wgOut->checkLastModified( $lastmod ) ){ + # Client cache fresh and headers sent, nothing more to do. + return; + } } - $hideliu = ($hideliu ? 1 : 0); - #$hideparams = "hideminor={$hideminor}&hideliu={$hideliu}&hidebots={$hidebots}"; - $urlparams = array( "hideminor" => $hideminor, "hideliu" => $hideliu, "hidebots" => $hidebots ); - $hideparams = wfArrayToCGI( $urlparams ); - - $minorLink = $sk->makeKnownLink( $wgLang->specialPage( "Recentchanges" ), - $showhide[1-$hideminor], wfArrayToCGI( array( "hideminor" => 1-$hideminor ), $urlparams ) ); - $botLink = $sk->makeKnownLink( $wgLang->specialPage( "Recentchanges" ), - $showhide[1-$hidebots], wfArrayToCGI( array( "hidebots" => 1-$hidebots ), $urlparams ) ); - $liuLink = $sk->makeKnownLink( $wgLang->specialPage( "Recentchanges" ), - $showhide[1-$hideliu], wfArrayToCGI( array( "hideliu" => 1-$hideliu ), $urlparams ) ); + + $hidem = $hideminor ? 'AND rc_minor=0' : ''; + $hidem .= $hidebots ? ' AND rc_bot=0' : ''; + $hidem .= $hideliu ? ' AND rc_user=0' : ''; + $hidem .= $hidepatrolled ? ' AND rc_patrolled=0' : ''; + $hidem .= is_null( $namespace ) ? '' : ' AND rc_namespace' . ($invert ? '!=' : '=') . $namespace; + + // This is the big thing! $uid = $wgUser->getID(); - $sql2 = "SELECT recentchanges.*" . ($uid ? ",wl_user" : "") . " FROM recentchanges " . - ($uid ? "LEFT OUTER JOIN watchlist ON wl_user={$uid} AND wl_title=rc_title AND wl_namespace=rc_namespace & 65534 " : "") . + + // Perform query + $sql2 = "SELECT *" . ($uid ? ",wl_user,wl_notificationtimestamp" : "") . " FROM $recentchanges " . + ($uid ? "LEFT OUTER JOIN $watchlist ON wl_user={$uid} AND wl_title=rc_title AND wl_namespace=rc_namespace " : "") . "WHERE rc_timestamp > '{$cutoff}' {$hidem} " . "ORDER BY rc_timestamp DESC LIMIT {$limit}"; + $res = $dbr->query( $sql2, $fname ); - $res = wfQuery( $sql2, DB_READ, $fname ); + // Fetch results, prepare a batch link existence check query $rows = array(); - while( $row = wfFetchObject( $res ) ){ - $rows[] = $row; + $batch = new LinkBatch; + while( $row = $dbr->fetchObject( $res ) ){ + $rows[] = $row; + // User page link + $title = Title::makeTitleSafe( NS_USER, $row->rc_user_text ); + $batch->addObj( $title ); + + // User talk + $title = Title::makeTitleSafe( NS_USER_TALK, $row->rc_user_text ); + $batch->addObj( $title ); + } + $dbr->freeResult( $res ); + + // Run existence checks + $batch->execute( $wgLinkCache ); - if(isset($from)) { - $note = wfMsg( "rcnotefrom", $limit, - $wgLang->timeanddate( $from, true ) ); + if( $feedFormat ) { + rcOutputFeed( $rows, $feedFormat, $limit, $hideminor, $lastmod ); } else { - $note = wfMsg( "rcnote", $limit, $days ); - } - $wgOut->addHTML( "\n
\n{$note}\n
" ); - $note = rcDayLimitLinks( $days, $limit, "Recentchanges", $hideparams, false, $minorLink, $botLink, $liuLink ); + # Web output... + + // Output header + if ( !$specialPage->including() ) { + $wgOut->addWikiText( wfMsgForContent( "recentchangestext" ) ); + + // Dump everything here + $nondefaults = array(); + + appendToArrayIfNotDefault( 'days', $days, $defaults, $nondefaults); + appendToArrayIfNotDefault( 'limit', $limit , $defaults, $nondefaults); + appendToArrayIfNotDefault( 'hideminor', $hideminor, $defaults, $nondefaults); + appendToArrayIfNotDefault( 'hidebots', $hidebots, $defaults, $nondefaults); + appendToArrayIfNotDefault( 'hideliu', $hideliu, $defaults, $nondefaults); + appendToArrayIfNotDefault( 'hidepatrolled', $hidepatrolled, $defaults, $nondefaults); + appendToArrayIfNotDefault( 'from', $from, $defaults, $nondefaults); + appendToArrayIfNotDefault( 'namespace', $namespace, $defaults, $nondefaults); + appendToArrayIfNotDefault( 'invert', $invert, $defaults, $nondefaults); + + // Add end of the texts + $wgOut->addHTML( '
' . rcOptionsPanel( $defaults, $nondefaults ) ); + $wgOut->addHTML( rcNamespaceForm( $namespace, $invert, $nondefaults) . '
'); + } + + // And now for the content + $sk = $wgUser->getSkin(); + $wgOut->setSyndicated( true ); + $list =& new ChangesList( $sk ); + $s = $list->beginRecentChangesList(); + $counter = 1; + foreach( $rows as $obj ){ + if( $limit == 0) { + break; + } - $note .= "
\n" . wfMsg( "rclistfrom", - $sk->makeKnownLink( $wgLang->specialPage( "Recentchanges" ), - $wgLang->timeanddate( $now, true ), "{$hideparams}&from=$now" ) ); + if ( ! ( $hideminor && $obj->rc_minor ) && + ! ( $hidepatrolled && $obj->rc_patrolled ) ) { + $rc = RecentChange::newFromRow( $obj ); + $rc->counter = $counter++; - $wgOut->addHTML( "{$note}\n" ); + if ($wgShowUpdatedMarker + && !empty( $obj->wl_notificationtimestamp ) + && ($obj->rc_timestamp >= $obj->wl_notificationtimestamp)) { + $rc->notificationtimestamp = true; + } else { + $rc->notificationtimestamp = false; + } - $s = $sk->beginRecentChangesList(); - foreach( $rows as $obj ){ - if( $limit == 0) { - break; + if ($wgRCShowWatchingUsers && $wgUser->getOption( 'shownumberswatching' )) { + $sql3 = "SELECT COUNT(*) AS n FROM $watchlist WHERE wl_title='" . $dbr->strencode($obj->rc_title) ."' AND wl_namespace=$obj->rc_namespace" ; + $res3 = $dbr->query( $sql3, 'wfSpecialRecentChanges'); + $x = $dbr->fetchObject( $res3 ); + $rc->numberofWatchingusers = $x->n; + } else { + $rc->numberofWatchingusers = 0; + } + $s .= $list->recentChangesLine( $rc, !empty( $obj->wl_user ) ); + --$limit; + } } + $s .= $list->endRecentChangesList(); + $wgOut->addHTML( $s ); + } +} - if ( ! ( $hideminor && $obj->rc_minor ) ) { - $rc = RecentChange::newFromRow( $obj ); - $s .= $sk->recentChangesLine( $rc, $obj->wl_user ); - --$limit; +function rcOutputFeed( $rows, $feedFormat, $limit, $hideminor, $lastmod ) { + global $messageMemc, $wgDBname, $wgFeedCacheTimeout; + global $wgFeedClasses, $wgTitle, $wgSitename, $wgContLanguageCode; + + if( !isset( $wgFeedClasses[$feedFormat] ) ) { + wfHttpError( 500, "Internal Server Error", "Unsupported feed type." ); + return false; + } + + $timekey = "$wgDBname:rcfeed:$feedFormat:timestamp"; + $key = "$wgDBname:rcfeed:$feedFormat:limit:$limit:minor:$hideminor"; + + $feedTitle = $wgSitename . ' - ' . wfMsgForContent( 'recentchanges' ) . + ' [' . $wgContLanguageCode . ']'; + $feed = new $wgFeedClasses[$feedFormat]( + $feedTitle, + htmlspecialchars( wfMsgForContent( 'recentchangestext' ) ), + $wgTitle->getFullUrl() ); + + /** + * 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 = false; + if( $feedLastmod = $messageMemc->get( $timekey ) ) { + /** + * If the cached feed was rendered very recently, we may + * go ahead and use it even if there have been edits made + * since it was rendered. This keeps a swarm of requests + * from being too bad on a super-frequently edited wiki. + */ + if( time() - wfTimestamp( TS_UNIX, $feedLastmod ) + < $wgFeedCacheTimeout + || wfTimestamp( TS_UNIX, $feedLastmod ) + > wfTimestamp( TS_UNIX, $lastmod ) ) { + wfDebug( "RC: loading feed from cache ($key; $feedLastmod; $lastmod)...\n" ); + $cachedFeed = $messageMemc->get( $key ); + } else { + wfDebug( "RC: cached feed timestamp check failed ($feedLastmod; $lastmod)\n" ); } } - $s .= $sk->endRecentChangesList(); + if( is_string( $cachedFeed ) ) { + wfDebug( "RC: Outputting cached feed\n" ); + $feed->httpHeaders(); + echo $cachedFeed; + } else { + wfDebug( "RC: rendering new feed and caching it\n" ); + ob_start(); + rcDoOutputFeed( $rows, $feed ); + $cachedFeed = ob_get_contents(); + ob_end_flush(); + + $expire = 3600 * 24; # One day + $messageMemc->set( $key, $cachedFeed ); + $messageMemc->set( $timekey, wfTimestamp( TS_MW ), $expire ); + } + return true; +} - wfFreeResult( $res ); - $wgOut->addHTML( $s ); +function rcDoOutputFeed( $rows, &$feed ) { + global $wgSitename, $wgFeedClasses, $wgContLanguageCode; + + $feed->outHeader(); + + # Merge adjacent edits by one user + $sorted = array(); + $n = 0; + foreach( $rows as $obj ) { + if( $n > 0 && + $obj->rc_namespace >= 0 && + $obj->rc_cur_id == $sorted[$n-1]->rc_cur_id && + $obj->rc_user_text == $sorted[$n-1]->rc_user_text ) { + $sorted[$n-1]->rc_last_oldid = $obj->rc_last_oldid; + } else { + $sorted[$n] = $obj; + $n++; + } + $first = false; + } + + foreach( $sorted as $obj ) { + $title = Title::makeTitle( $obj->rc_namespace, $obj->rc_title ); + $talkpage = $title->getTalkPage(); + $item = new FeedItem( + $title->getPrefixedText(), + rcFormatDiff( $obj ), + $title->getFullURL(), + $obj->rc_timestamp, + $obj->rc_user_text, + $talkpage->getFullURL() + ); + $feed->outItem( $item ); + } + $feed->outFooter(); } -function rcCountLink( $lim, $d, $page="Recentchanges", $more="" ) -{ - global $wgUser, $wgLang; +/** + * + */ +function rcCountLink( $lim, $d, $page='Recentchanges', $more='' ) { + global $wgUser, $wgLang, $wgContLang; $sk = $wgUser->getSkin(); - $s = $sk->makeKnownLink( $wgLang->specialPage( $page ), - ($lim ? "{$lim}" : wfMsg( "all" ) ), "{$more}" . - ($d ? "days={$d}&" : "") . "limit={$lim}" ); + $s = $sk->makeKnownLink( $wgContLang->specialPage( $page ), + ($lim ? $wgLang->formatNum( "{$lim}" ) : wfMsg( 'recentchangesall' ) ), "{$more}" . + ($d ? "days={$d}&" : '') . 'limit='.$lim ); return $s; } -function rcDaysLink( $lim, $d, $page="Recentchanges", $more="" ) -{ - global $wgUser, $wgLang; +/** + * + */ +function rcDaysLink( $lim, $d, $page='Recentchanges', $more='' ) { + global $wgUser, $wgLang, $wgContLang; $sk = $wgUser->getSkin(); - $s = $sk->makeKnownLink( $wgLang->specialPage( $page ), - ($d ? "{$d}" : wfMsg( "all" ) ), "{$more}days={$d}" . - ($lim ? "&limit={$lim}" : "") ); + $s = $sk->makeKnownLink( $wgContLang->specialPage( $page ), + ($d ? $wgLang->formatNum( "{$d}" ) : wfMsg( 'recentchangesall' ) ), $more.'days='.$d . + ($lim ? '&limit='.$lim : '') ); return $s; } -function rcDayLimitLinks( $days, $limit, $page="Recentchanges", $more="", $doall = false, $minorLink = "", - $botLink = "", $liuLink = "" ) -{ - if ($more != "") $more .= "&"; - $cl = rcCountLink( 50, $days, $page, $more ) . " | " . - rcCountLink( 100, $days, $page, $more ) . " | " . - rcCountLink( 250, $days, $page, $more ) . " | " . +/** + * Used by Recentchangeslinked + */ +function rcDayLimitLinks( $days, $limit, $page='Recentchanges', $more='', $doall = false, $minorLink = '', + $botLink = '', $liuLink = '', $patrLink = '' ) { + if ($more != '') $more .= '&'; + $cl = rcCountLink( 50, $days, $page, $more ) . ' | ' . + rcCountLink( 100, $days, $page, $more ) . ' | ' . + rcCountLink( 250, $days, $page, $more ) . ' | ' . rcCountLink( 500, $days, $page, $more ) . - ( $doall ? ( " | " . rcCountLink( 0, $days, $page, $more ) ) : "" ); - $dl = rcDaysLink( $limit, 1, $page, $more ) . " | " . - rcDaysLink( $limit, 3, $page, $more ) . " | " . - rcDaysLink( $limit, 7, $page, $more ) . " | " . - rcDaysLink( $limit, 14, $page, $more ) . " | " . + ( $doall ? ( ' | ' . rcCountLink( 0, $days, $page, $more ) ) : '' ); + $dl = rcDaysLink( $limit, 1, $page, $more ) . ' | ' . + rcDaysLink( $limit, 3, $page, $more ) . ' | ' . + rcDaysLink( $limit, 7, $page, $more ) . ' | ' . + rcDaysLink( $limit, 14, $page, $more ) . ' | ' . rcDaysLink( $limit, 30, $page, $more ) . - ( $doall ? ( " | " . rcDaysLink( $limit, 0, $page, $more ) ) : "" ); - $shm = wfMsg( "showhideminor", $minorLink, $botLink, $liuLink ); - $note = wfMsg( "rclinks", $cl, $dl, $shm ); + ( $doall ? ( ' | ' . rcDaysLink( $limit, 0, $page, $more ) ) : '' ); + $shm = wfMsg( 'showhideminor', $minorLink, $botLink, $liuLink, $patrLink ); + $note = wfMsg( 'rclinks', $cl, $dl, $shm ); return $note; } -# Obsolete? Isn't called from anywhere and $mlink isn't defined -function rcLimitLinks( $page="Recentchanges", $more="", $doall = false ) + +/** + * Makes change an option link which carries all the other options + */ +function makeOptionsLink( $title, $override, $options ) { + global $wgUser, $wgLang, $wgContLang; + $sk = $wgUser->getSkin(); + return $sk->makeKnownLink( $wgContLang->specialPage( 'Recentchanges' ), + $title, wfArrayToCGI( $override, $options ) ); +} + +/** + * Creates the options panel + */ +function rcOptionsPanel( $defaults, $nondefaults ) { + global $wgLang; + + $options = $nondefaults + $defaults; + + if( $options['from'] ) + $note = wfMsg( 'rcnotefrom', $wgLang->formatNum( $options['limit'] ), $wgLang->timeanddate( $options['from'], true ) ); + else + $note = wfMsg( 'rcnote', $wgLang->formatNum( $options['limit'] ), $wgLang->formatNum( $options['days'] ) ); + + // limit links + $cl = ''; + $options_limit = array(50, 100, 250, 500); + $i = 0; + while ( $i+1 < count($options_limit) ) { + $cl .= makeOptionsLink( $options_limit[$i], array( 'limit' => $options_limit[$i] ), $nondefaults) . ' | ' ; + $i++; + } + $cl .= makeOptionsLink( $options_limit[$i], array( 'limit' => $options_limit[$i] ), $nondefaults) ; + + // day links, reset 'from' to none + $dl = ''; + $options_days = array(1, 3, 7, 14, 30); + $i = 0; + while ( $i+1 < count($options_days) ) { + $dl .= makeOptionsLink( $options_days[$i], array( 'days' => $options_days[$i], 'from' => '' ), $nondefaults) . ' | ' ; + $i++; + } + $dl .= makeOptionsLink( $options_days[$i], array( 'days' => $options_days[$i], 'from' => '' ), $nondefaults) ; + + // show/hide links + $showhide = array( wfMsg( 'show' ), wfMsg( 'hide' )); + $minorLink = makeOptionsLink( $showhide[1-$options['hideminor']], + array( 'hideminor' => 1-$options['hideminor'] ), $nondefaults); + $botLink = makeOptionsLink( $showhide[1-$options['hidebots']], + array( 'hidebots' => 1-$options['hidebots'] ), $nondefaults); + $liuLink = makeOptionsLink( $showhide[1-$options['hideliu']], + array( 'hideliu' => 1-$options['hideliu'] ), $nondefaults); + $patrLink = makeOptionsLink( $showhide[1-$options['hidepatrolled']], + array( 'hidepatrolled' => 1-$options['hidepatrolled'] ), $nondefaults); + + $hl = wfMsg( 'showhideminor', $minorLink, $botLink, $liuLink, $patrLink ); + + // show from this onward link + $now = $wgLang->timeanddate( wfTimestampNow(), true ); + $tl = makeOptionsLink( $now, array( 'from' => wfTimestampNow()), $nondefaults ); + + $rclinks = wfMsg( 'rclinks', $cl, $dl, $hl ); + $rclistfrom = wfMsg( 'rclistfrom', $tl ); + return "$note
$rclinks
$rclistfrom"; + +} + +/** + * Creates the choose namespace selection + * + * @access private + * + * @param mixed $namespace The key of the currently selected namespace, empty string + * if there is none + * @param bool $invert Whether to invert the namespace selection + * @param array $nondefaults An array of non default options to be remembered + * + * @return string + */ +function rcNamespaceForm ( $namespace, $invert, $nondefaults ) { + global $wgContLang, $wgScript; + $t = Title::makeTitle( NS_SPECIAL, 'Recentchanges' ); + + $namespaceselect = "'; + + $out = ''; + $out .= "
\n"; + foreach ( $nondefaults as $key => $value ) { + if ($key != 'namespace' && $key != 'invert') + $out .= ""; + } + + $submitbutton = ''; + $invertbox = "'; + + + $out .= ''; + $out .= " +
+ + $namespaceselect $submitbutton $invertbox +
"; + $out .= '
'; + return $out; +} + + +/** + * Format a diff for the newsfeed + */ +function rcFormatDiff( $row ) { + $fname = 'rcFormatDiff'; + wfProfileIn( $fname ); + + require_once( 'DifferenceEngine.php' ); + $comment = "

" . htmlspecialchars( $row->rc_comment ) . "

\n"; + + if( $row->rc_namespace >= 0 ) { + global $wgContLang; + + #$diff =& new DifferenceEngine( $row->rc_this_oldid, $row->rc_last_oldid, $row->rc_id ); + #$diff->showDiffPage(); + + $titleObj = Title::makeTitle( $row->rc_namespace, $row->rc_title ); + $dbr =& wfGetDB( DB_SLAVE ); + $newrev =& Revision::newFromTitle( $titleObj, $row->rc_this_oldid ); + if( $newrev ) { + $newtext = $newrev->getText(); + } else { + $diffText = "

Can't load revision $row->rc_this_oldid

"; + wfProfileOut( $fname ); + return $comment . $diffText; + } + + if( $row->rc_last_oldid ) { + wfProfileIn( "$fname-dodiff" ); + $oldrev =& Revision::newFromId( $row->rc_last_oldid ); + if( !$oldrev ) { + $diffText = "

Can't load old revision $row->rc_last_oldid

"; + wfProfileOut( $fname ); + return $comment . $diffText; + } + $oldtext = $oldrev->getText(); + + # Old entries may contain illegal characters + # which will damage output + $oldtext = UtfNormal::cleanUp( $oldtext ); + + global $wgFeedDiffCutoff; + if( strlen( $newtext ) > $wgFeedDiffCutoff || + strlen( $oldtext ) > $wgFeedDiffCutoff ) { + $diffLink = $titleObj->escapeFullUrl( + 'diff=' . $row->rc_this_oldid . + '&oldid=' . $row->rc_last_oldid ); + $diffText = '' . + htmlspecialchars( wfMsgForContent( 'difference' ) ) . + ''; + } else { + $diffText = DifferenceEngine::getDiff( $oldtext, $newtext, + wfMsg( 'revisionasof', $wgContLang->timeanddate( $row->rc_timestamp ) ), + wfMsg( 'currentrev' ) ); + } + wfProfileOut( "$fname-dodiff" ); + } else { + $diffText = '

' . wfMsg( 'newpage' ) . '

' . + '
' . nl2br( htmlspecialchars( $newtext ) ) . '
'; + } + + wfProfileOut( $fname ); + return $comment . $diffText; + } + + wfProfileOut( $fname ); + return $comment; +} + + +/** + * Appends to second array if $value differs from that in $default + */ +function appendToArrayIfNotDefault( $key, $value, $default, &$changed ) { - if ($more != "") $more .= "&"; - $cl = rcCountLink( 50, 0, $page, $more ) . " | " . - rcCountLink( 100, 0, $page, $more ) . " | " . - rcCountLink( 250, 0, $page, $more ) . " | " . - rcCountLink( 500, 0, $page, $more ) . - ( $doall ? ( " | " . rcCountLink( 0, $days, $page, $more ) ) : "" ); - $note = wfMsg( "rclinks", $cl, "", $mlink ); - return $note; + if ( is_null( $changed ) ) { + die(); + } + if ( $default[$key] !== $value ) { + $changed[$key] = $value; + } } ?>