| Current File : /home/jvzmxxx/wiki1/extensions/SocialProfile/UserStats/GenerateTopUsersReport.php |
<?php
/**
* A special page to generate the report of the users who earned the most
* points during the past week or month. This is the only way to update the
* points_winner_weekly and points_winner_monthly columns in the user_stats
* table.
*
* This special page also creates a weekly report in the project namespace.
* The name of that page is controlled by two system messages,
* MediaWiki:User-stats-report-weekly-page-title and
* MediaWiki:User-stats-report-monthly-page-title (depending on the type of the
* report).
*
* @file
* @ingroup Extensions
*/
class GenerateTopUsersReport extends SpecialPage {
/**
* Constructor -- set up the new special page
*/
public function __construct() {
parent::__construct( 'GenerateTopUsersReport', 'generatetopusersreport' );
}
public function doesWrites() {
return true;
}
/**
* Show the special page
*
* @param $period String: either weekly or monthly
*/
public function execute( $period ) {
global $wgContLang, $wgUser;
global $wgUserStatsPointValues;
$out = $this->getOutput();
$request = $this->getRequest();
$user = $this->getUser();
// Blocked through Special:Block? Tough luck.
if ( $user->isBlocked() ) {
throw new UserBlockedError( $user->getBlock() );
}
// Is the database locked or not?
if ( wfReadOnly() ) {
$out->readOnlyPage();
return false;
}
// Check for the correct permission
if ( !$user->isAllowed( 'generatetopusersreport' ) ) {
throw new PermissionsError( 'generatetopusersreport' );
}
// Set the page title, robot policy, etc.
$this->setHeaders();
$period = $request->getVal( 'period', $period );
// If we don't have a period, default to weekly or else we'll be
// hitting a database error because when constructing table names
// later on in the code, we assume that $period is set to something
if ( !$period ) {
$period = 'weekly';
}
// Make sure that we are actually going to give out some extra points
// for weekly and/or monthly wins, depending on which report we're
// generating here. If not, there's no point in continuing.
if ( empty( $wgUserStatsPointValues["points_winner_{$period}"] ) ) {
$out->addHTML( $this->msg( 'user-stats-report-error-variable-not-set', $period )->escaped() );
return;
}
// There used to be a lot of inline CSS here in the original version.
// I removed that, because most of it is already in TopList.css, inline
// CSS (and JS, for that matter) is evil, there were only 5 CSS
// declarations that weren't in TopList.css and it was making the
// display look worse, not better.
// Add CSS
$out->addModuleStyles( 'ext.socialprofile.userstats.css' );
// Used as the LIMIT for SQL queries; basically, show this many users
// in the generated reports.
$user_count = $request->getInt( 'user_count', 10 );
if( $period == 'weekly' ) {
$period_title = $wgContLang->date( wfTimestamp( TS_MW, strtotime( '-1 week' ) ) ) .
'-' . $wgContLang->date( wfTimestampNow() );
} elseif ( $period == 'monthly' ) {
$date = getdate(); // It's a PHP core function
$period_title = $wgContLang->getMonthName( $date['mon'] ) .
' ' . $date['year'];
}
$dbw = wfGetDB( DB_MASTER );
// Query the appropriate points table
$res = $dbw->select(
"user_points_{$period}",
array( 'up_user_id', 'up_user_name', 'up_points' ),
array(),
__METHOD__,
array( 'ORDER BY' => 'up_points DESC', 'LIMIT' => $user_count )
);
$last_rank = 0;
$last_total = 0;
$x = 1;
$users = array();
// Initial run is a special case
if ( $dbw->numRows( $res ) <= 0 ) {
// For the initial run, everybody's a winner!
// Yes, I know that this isn't ideal and I'm sorry about that.
// The original code just wouldn't work if the first query
// (the $res above) returned nothing so I had to work around that
// limitation.
$res = $dbw->select(
'user_stats',
array( 'stats_user_id', 'stats_user_name', 'stats_total_points' ),
array(),
__METHOD__,
array(
'ORDER BY' => 'stats_total_points DESC',
'LIMIT' => $user_count
)
);
$output = '<div class="top-users">';
foreach ( $res as $row ) {
if ( $row->stats_total_points == $last_total ) {
$rank = $last_rank;
} else {
$rank = $x;
}
$last_rank = $x;
$last_total = $row->stats_total_points;
$x++;
$users[] = array(
'user_id' => $row->stats_user_id,
'user_name' => $row->stats_user_name,
'points' => $row->stats_total_points,
'rank' => $rank
);
}
} else {
$output = '<div class="top-users">';
foreach ( $res as $row ) {
if ( $row->up_points == $last_total ) {
$rank = $last_rank;
} else {
$rank = $x;
}
$last_rank = $x;
$last_total = $row->up_points;
$x++;
$users[] = array(
'user_id' => $row->up_user_id,
'user_name' => $row->up_user_name,
'points' => $row->up_points,
'rank' => $rank
);
}
}
$winner_count = 0;
$winners = '';
if ( !empty( $users ) ) {
$localizedUserNS = $wgContLang->getNsText( NS_USER );
foreach ( $users as $user ) {
if ( $user['rank'] == 1 ) {
// Mark the user ranked #1 as the "winner" for the given
// period
$stats = new UserStatsTrack( $user['user_id'], $user['user_name'] );
$stats->incStatField( "points_winner_{$period}" );
if ( $winners ) {
$winners .= ', ';
}
$winners .= "[[{$localizedUserNS}:{$user['user_name']}|{$user['user_name']}]]";
$winner_count++;
}
}
}
// Start building the content of the report page
$pageContent = "__NOTOC__\n";
// For grep: user-stats-weekly-winners, user-stats-monthly-winners
$pageContent .= '==' . $this->msg(
"user-stats-{$period}-winners"
)->numParams( $winner_count )->inContentLanguage()->parse() . "==\n\n";
// For grep: user-stats-weekly-win-congratulations, user-stats-monthly-win-congratulations
$pageContent .= $this->msg(
"user-stats-{$period}-win-congratulations"
)->numParams(
$winner_count,
$wgContLang->formatNum( $wgUserStatsPointValues["points_winner_{$period}"] )
)->inContentLanguage()->parse() . "\n\n";
$pageContent .= "=={$winners}==\n\n<br />\n";
$pageContent .= '==' . $this->msg( 'user-stats-full-top' )->numParams(
$wgContLang->formatNum( $user_count ) )->inContentLanguage()->parse() . "==\n\n";
foreach( $users as $user ) {
$userTitle = Title::makeTitle( NS_USER, $user['user_name'] );
$pageContent .= $this->msg(
'user-stats-report-row',
$wgContLang->formatNum( $user['rank'] ),
$user['user_name'],
$wgContLang->formatNum( $user['points'] )
)->inContentLanguage()->parse() . "\n\n";
$output .= "<div class=\"top-fan-row\">
<span class=\"top-fan-num\">{$user['rank']}</span><span class=\"top-fan\"> <a href='" .
$userTitle->getFullURL() . "' >" . $user['user_name'] . "</a>
</span>";
$output .= '<span class="top-fan-points">' . $this->msg(
'user-stats-report-points',
$wgContLang->formatNum( $user['points'] )
)->inContentLanguage()->parse() . '</span>
</div>';
}
// Make the edit as MediaWiki default
$oldUser = $wgUser;
$wgUser = User::newFromName( 'MediaWiki default' );
$wgUser->addGroup( 'bot' );
// Add a note to the page that it was automatically generated
$pageContent .= "\n\n''" . $this->msg( 'user-stats-report-generation-note' )->parse() . "''\n\n";
// Create the Title object that represents the report page
// For grep: user-stats-report-weekly-page-title, user-stats-report-monthly-page-title
$title = Title::makeTitleSafe(
NS_PROJECT,
$this->msg( "user-stats-report-{$period}-page-title", $period_title )->inContentLanguage()->escaped()
);
$article = new Article( $title );
// If the article doesn't exist, create it!
// @todo Would there be any point in updating a pre-existing article?
// I think not, but...
if ( !$article->exists() ) {
// For grep: user-stats-report-weekly-edit-summary, user-stats-report-monthly-edit-summary
$article->doEditContent(
ContentHandler::makeContent( $pageContent, $title ),
$this->msg( "user-stats-report-{$period}-edit-summary" )->inContentLanguage()->escaped()
);
$date = date( 'Y-m-d H:i:s' );
// Archive points from the weekly/monthly table into the archive
// table
$dbw->insertSelect(
'user_points_archive',
"user_points_{$period}",
array(
'up_user_name' => 'up_user_name',
'up_user_id' => 'up_user_id',
'up_points' => 'up_points',
'up_period' => ( ( $period == 'weekly' ) ? 1 : 2 ),
'up_date' => $dbw->addQuotes( $date )
),
'*',
__METHOD__
);
// Clear the current point table to make way for the next period
$res = $dbw->delete( "user_points_{$period}", '*', __METHOD__ );
}
// Switch the user back
$wgUser = $oldUser;
$output .= '</div>'; // .top-users
$out->addHTML( $output );
}
}