mirror of
https://github.com/scratchfoundation/swiki-confirmaccount.git
synced 2024-12-04 12:51:01 -05:00
added files
This commit is contained in:
commit
4d9306b06c
32 changed files with 20436 additions and 0 deletions
4
ConfirmAccount/.gitignore
vendored
Normal file
4
ConfirmAccount/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
.svn
|
||||
*~
|
||||
*.kate-swp
|
||||
.*.swp
|
6
ConfirmAccount/.gitreview
Normal file
6
ConfirmAccount/.gitreview
Normal file
|
@ -0,0 +1,6 @@
|
|||
[gerrit]
|
||||
host=gerrit.wikimedia.org
|
||||
port=29418
|
||||
project=mediawiki/extensions/ConfirmAccount
|
||||
defaultbranch=master
|
||||
defaultrebase=0
|
118
ConfirmAccount/ConfirmAccount.config.php
Normal file
118
ConfirmAccount/ConfirmAccount.config.php
Normal file
|
@ -0,0 +1,118 @@
|
|||
<?php
|
||||
|
||||
# ######## Configuration variables ########
|
||||
# IMPORTANT: DO NOT EDIT THIS FILE
|
||||
# When configuring globals, set them at LocalSettings.php instead
|
||||
|
||||
# Set the person's bio as their userpage?
|
||||
$wgMakeUserPageFromBio = true;
|
||||
# Text to add to bio pages if the above option is on
|
||||
$wgAutoUserBioText = '';
|
||||
|
||||
# Create a user talk page with a welcome message for accepted users.
|
||||
# The message can be customized by editing MediaWiki:confirmaccount-welc.
|
||||
$wgAutoWelcomeNewUsers = true;
|
||||
|
||||
# How long to store rejected requests
|
||||
$wgRejectedAccountMaxAge = 7 * 24 * 3600; // 1 week
|
||||
# How long after accounts have been requested/held before they count as 'rejected'
|
||||
$wgConfirmAccountRejectAge = 30 * 24 * 3600; // 1 month
|
||||
|
||||
# How many requests can an IP make at once?
|
||||
$wgAccountRequestThrottle = 1;
|
||||
# Can blocked users with "prevent account creation" request accounts?
|
||||
$wgAccountRequestWhileBlocked = false;
|
||||
|
||||
# Which form elements to show at Special:RequestAccount
|
||||
$wgConfirmAccountRequestFormItems = array(
|
||||
# Let users make names other than their "real name"
|
||||
'UserName' => array( 'enabled' => true ),
|
||||
# Real name of user
|
||||
'RealName' => array( 'enabled' => false ),
|
||||
# Biographical info
|
||||
'Biography' => array( 'enabled' => false, 'minWords' => 0 ),
|
||||
# Interest checkboxes (defined in MediaWiki:requestaccount-areas)
|
||||
'AreasOfInterest' => array( 'enabled' => true ),
|
||||
# CV/resume attachment option
|
||||
'CV' => array( 'enabled' => false ),
|
||||
# Additional non-public info for reviewer
|
||||
'Notes' => array( 'enabled' => true ),
|
||||
# Option to place web URLs that establish the user
|
||||
'Links' => array( 'enabled' => false ),
|
||||
# Terms of Service checkbox
|
||||
'TermsOfService' => array( 'enabled' => true ),
|
||||
);
|
||||
|
||||
# If files can be attached, what types can be used? (MIME data is checked)
|
||||
$wgAccountRequestExts = array( 'txt', 'pdf', 'doc', 'latex', 'rtf', 'text', 'wp', 'wpd', 'sxw' );
|
||||
|
||||
# Prospective account request types.
|
||||
# Format is an array of (integer => (subpage param,user group,autotext)) pairs.
|
||||
# The integer keys enumerate the request types. The key for a type should not change.
|
||||
# Each type has its own request queue at Special:ConfirmAccount/<subpage param>.
|
||||
# When a request of a certain type is approved, the new user:
|
||||
# (a) is placed in the <user group> group (if not User or *)
|
||||
# (b) has <autotext> appended to his or her user page
|
||||
$wgAccountRequestTypes = array(
|
||||
0 => array( 'authors', 'user', null )
|
||||
);
|
||||
|
||||
# If set, will add {{DEFAULTSORT:sortkey}} to userpages for auto-categories.
|
||||
# The sortkey will be made by doing a regex search and replace on the title.
|
||||
# Set this variable to false to avoid sortkey use.
|
||||
$wgConfirmAccountSortkey = false;
|
||||
// For example, the below will do {{DEFAULTSORT:firstname, lastname}}
|
||||
# $wgConfirmAccountSortkey = array( '/^(.+) ([^ ]+)$/', '$2, $1' );
|
||||
|
||||
# IMPORTANT: do we store the user's notes and credentials
|
||||
# for sucessful account request? This will be stored indefinetely
|
||||
# and will be accessible to users with crediential lookup permissions
|
||||
$wgConfirmAccountSaveInfo = true;
|
||||
|
||||
# Send an email to this address when account requestors confirm their email.
|
||||
# Set to false to skip this
|
||||
$wgConfirmAccountContact = false;
|
||||
|
||||
# If ConfirmEdit is installed and set to trigger for createaccount,
|
||||
# inject catpchas for requests too?
|
||||
$wgConfirmAccountCaptchas = true;
|
||||
|
||||
# Storage repos. Has B/C for when this used FileStore.
|
||||
$wgConfirmAccountFSRepos = array(
|
||||
'accountreqs' => array( # Location of attached files for pending requests
|
||||
'name' => 'accountreqs',
|
||||
'directory' => isset( $wgFileStore['accountreqs'] ) ?
|
||||
$wgFileStore['accountreqs']['directory'] : "{$IP}/images/accountreqs",
|
||||
'url' => isset( $wgFileStore['accountreqs'] ) ?
|
||||
$wgFileStore['accountreqs']['url'] : null,
|
||||
'hashLevels' => isset( $wgFileStore['accountreqs'] ) ?
|
||||
$wgFileStore['accountreqs']['hash'] : 3
|
||||
),
|
||||
'accountcreds' => array( # Location of credential files
|
||||
'name' => 'accountcreds',
|
||||
'directory' => isset( $wgFileStore['accountcreds'] ) ?
|
||||
$wgFileStore['accountcreds']['directory'] : "{$IP}/images/accountcreds",
|
||||
'url' => isset( $wgFileStore['accountcreds'] ) ?
|
||||
$wgFileStore['accountcreds']['url'] : null,
|
||||
'hashLevels' => isset( $wgFileStore['accountcreds'] ) ?
|
||||
$wgFileStore['accountcreds']['hash'] : 3
|
||||
)
|
||||
);
|
||||
|
||||
# Restrict account creation
|
||||
$wgGroupPermissions['*']['createaccount'] = false;
|
||||
$wgGroupPermissions['user']['createaccount'] = false;
|
||||
# Grant account queue rights
|
||||
$wgGroupPermissions['bureaucrat']['confirmaccount'] = true;
|
||||
# This right has the request IP show when confirming accounts
|
||||
$wgGroupPermissions['bureaucrat']['requestips'] = true;
|
||||
|
||||
# If credentials are stored, this right lets users look them up
|
||||
$wgGroupPermissions['bureaucrat']['lookupcredentials'] = true;
|
||||
|
||||
# Show notice for open requests to admins?
|
||||
# This is cached, but still can be expensive on sites with thousands of requests.
|
||||
$wgConfirmAccountNotice = true;
|
||||
|
||||
# End of configuration variables.
|
||||
# ########
|
81
ConfirmAccount/ConfirmAccount.php
Normal file
81
ConfirmAccount/ConfirmAccount.php
Normal file
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
/*
|
||||
(c) Aaron Schulz 2007, GPL
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
if ( !defined( 'MEDIAWIKI' ) ) {
|
||||
echo "ConfirmAccount extension\n";
|
||||
exit( 1 ) ;
|
||||
}
|
||||
|
||||
$wgExtensionCredits['specialpage'][] = array(
|
||||
'path' => __FILE__,
|
||||
'name' => 'Confirm User Accounts',
|
||||
'descriptionmsg' => 'confirmedit-desc',
|
||||
'author' => 'Aaron Schulz',
|
||||
'url' => 'https://www.mediawiki.org/wiki/Extension:ConfirmAccount',
|
||||
);
|
||||
|
||||
# Load default config variables
|
||||
require( dirname( __FILE__ ) . '/ConfirmAccount.config.php' );
|
||||
|
||||
# Define were PHP files and i18n files are located
|
||||
require( dirname( __FILE__ ) . '/ConfirmAccount.setup.php' );
|
||||
ConfirmAccountSetup::defineSourcePaths( $wgAutoloadClasses, $wgExtensionMessagesFiles );
|
||||
|
||||
# Define JS/CSS modules and file locations
|
||||
ConfirmAccountUISetup::defineResourceModules( $wgResourceModules );
|
||||
|
||||
# Let some users confirm account requests and view credentials for created accounts
|
||||
$wgAvailableRights[] = 'confirmaccount'; // user can confirm account requests
|
||||
$wgAvailableRights[] = 'requestips'; // user can see IPs in request queue
|
||||
$wgAvailableRights[] = 'lookupcredentials'; // user can lookup info on confirmed users
|
||||
|
||||
# Actually register special pages
|
||||
ConfirmAccountUISetup::defineSpecialPages( $wgSpecialPages, $wgSpecialPageGroups );
|
||||
|
||||
# ####### HOOK CALLBACK FUNCTIONS #########
|
||||
|
||||
# UI-related hook handlers
|
||||
ConfirmAccountUISetup::defineHookHandlers( $wgHooks );
|
||||
|
||||
# Check for account name collisions
|
||||
$wgHooks['AbortNewAccount'][] = 'ConfirmAccountUIHooks::checkIfAccountNameIsPending';
|
||||
|
||||
# Schema changes
|
||||
$wgHooks['LoadExtensionSchemaUpdates'][] = 'ConfirmAccountUpdaterHooks::addSchemaUpdates';
|
||||
|
||||
# ####### END HOOK CALLBACK FUNCTIONS #########
|
||||
|
||||
# Load the extension after setup is finished
|
||||
$wgExtensionFunctions[] = 'efLoadConfirmAccount';
|
||||
|
||||
/**
|
||||
* This function is for setup that has to happen in Setup.php
|
||||
* when the functions in $wgExtensionFunctions get executed.
|
||||
* @return void
|
||||
*/
|
||||
function efLoadConfirmAccount() {
|
||||
global $wgEnableEmail;
|
||||
# This extension needs email enabled!
|
||||
# Otherwise users can't get their passwords...
|
||||
if ( !$wgEnableEmail ) {
|
||||
echo "ConfirmAccount extension requires \$wgEnableEmail set to true.\n";
|
||||
exit( 1 ) ;
|
||||
}
|
||||
}
|
56
ConfirmAccount/ConfirmAccount.setup.php
Normal file
56
ConfirmAccount/ConfirmAccount.setup.php
Normal file
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
/**
|
||||
* Class containing basic setup functions.
|
||||
*/
|
||||
class ConfirmAccountSetup {
|
||||
/**
|
||||
* Register source code paths.
|
||||
* This function must NOT depend on any config vars.
|
||||
*
|
||||
* @param $classes Array $classes
|
||||
* @param $messagesFiles Array $messagesFiles
|
||||
* @return void
|
||||
*/
|
||||
public static function defineSourcePaths( array &$classes, array &$messagesFiles ) {
|
||||
$dir = dirname( __FILE__ );
|
||||
|
||||
# Basic directory layout
|
||||
$backendDir = "$dir/backend";
|
||||
$schemaDir = "$dir/backend/schema";
|
||||
$businessDir = "$dir/business";
|
||||
$frontendDir = "$dir/frontend";
|
||||
$langDir = "$dir/frontend/language/";
|
||||
$spActionDir = "$dir/frontend/specialpages/actions";
|
||||
|
||||
# Main i18n file and special page alias file
|
||||
$messagesFiles['ConfirmAccount'] = "$langDir/ConfirmAccount.i18n.php";
|
||||
$messagesFiles['ConfirmAccountAliases'] = "$langDir/ConfirmAccount.alias.php";
|
||||
|
||||
# UI setup class
|
||||
$classes['ConfirmAccountUISetup'] = "$frontendDir/ConfirmAccountUI.setup.php";
|
||||
# UI event handler classes
|
||||
$classes['ConfirmAccountUIHooks'] = "$frontendDir/ConfirmAccountUI.hooks.php";
|
||||
|
||||
# UI to request an account
|
||||
$classes['RequestAccountPage'] = "$spActionDir/RequestAccount_body.php";
|
||||
$messagesFiles['RequestAccountPage'] = "$langDir/RequestAccountPage.i18n.php";
|
||||
# UI to confirm accounts
|
||||
$classes['ConfirmAccountsPage'] = "$spActionDir/ConfirmAccount_body.php";
|
||||
$messagesFiles['ConfirmAccountPage'] = "$langDir/ConfirmAccountPage.i18n.php";
|
||||
# UI to see account credentials
|
||||
$classes['UserCredentialsPage'] = "$spActionDir/UserCredentials_body.php";
|
||||
$messagesFiles['UserCredentialsPage'] = "$langDir/UserCredentialsPage.i18n.php";
|
||||
|
||||
# Utility functions
|
||||
$classes['ConfirmAccount'] = "$backendDir/ConfirmAccount.class.php";
|
||||
# Data access objects
|
||||
$classes['UserAccountRequest'] = "$backendDir/UserAccountRequest.php";
|
||||
|
||||
# Business logic
|
||||
$classes['AccountRequestSubmission'] = "$businessDir/AccountRequestSubmission.php";
|
||||
$classes['AccountConfirmSubmission'] = "$businessDir/AccountConfirmSubmission.php";
|
||||
|
||||
# Schema changes
|
||||
$classes['ConfirmAccountUpdaterHooks'] = "$schemaDir/ConfirmAccountUpdater.hooks.php";
|
||||
}
|
||||
}
|
11
ConfirmAccount/README.txt
Normal file
11
ConfirmAccount/README.txt
Normal file
|
@ -0,0 +1,11 @@
|
|||
Complete online documenation:
|
||||
http://www.mediawiki.org/wiki/Extension:ConfirmAccount
|
||||
|
||||
== Breaking changes ==
|
||||
=== MediaWiki 1.20 ===
|
||||
$wgAccountRequestMinWords, $wgAccountRequestToS, $wgAccountRequestExtraInfo,
|
||||
and $wgAllowAccountRequestFiles were all folded into a new variable called
|
||||
$wgConfirmAccountRequestFormItems.
|
||||
|
||||
== Licensing ==
|
||||
© GPL, Aaron Schulz
|
307
ConfirmAccount/backend/ConfirmAccount.class.php
Normal file
307
ConfirmAccount/backend/ConfirmAccount.class.php
Normal file
|
@ -0,0 +1,307 @@
|
|||
<?php
|
||||
class ConfirmAccount {
|
||||
/**
|
||||
* Move old stale requests to rejected list. Delete old rejected requests.
|
||||
*/
|
||||
public static function runAutoMaintenance() {
|
||||
global $wgRejectedAccountMaxAge, $wgConfirmAccountRejectAge, $wgConfirmAccountFSRepos;
|
||||
|
||||
$dbw = wfGetDB( DB_MASTER );
|
||||
$repo = new FSRepo( $wgConfirmAccountFSRepos['accountreqs'] );
|
||||
|
||||
# Select all items older than time $encCutoff
|
||||
$encCutoff = $dbw->addQuotes( $dbw->timestamp( time() - $wgRejectedAccountMaxAge ) );
|
||||
$res = $dbw->select( 'account_requests',
|
||||
array( 'acr_id', 'acr_storage_key' ),
|
||||
array( "acr_rejected < {$encCutoff}" ),
|
||||
__METHOD__
|
||||
);
|
||||
|
||||
# Clear out any associated attachments and delete those rows
|
||||
foreach ( $res as $row ) {
|
||||
$key = $row->acr_storage_key;
|
||||
if ( $key ) {
|
||||
$path = $repo->getZonePath( 'public' ) . '/' .
|
||||
UserAccountRequest::relPathFromKey( $key );
|
||||
if ( $path && file_exists( $path ) ) {
|
||||
unlink( $path );
|
||||
}
|
||||
}
|
||||
$dbw->delete( 'account_requests', array( 'acr_id' => $row->acr_id ), __METHOD__ );
|
||||
}
|
||||
|
||||
# Select all items older than time $encCutoff
|
||||
$encCutoff = $dbw->addQuotes( $dbw->timestamp( time() - $wgConfirmAccountRejectAge ) );
|
||||
# Old stale accounts will count as rejected. If the request was held, give it more time.
|
||||
$dbw->update( 'account_requests',
|
||||
array( 'acr_rejected' => $dbw->timestamp(),
|
||||
'acr_user' => 0, // dummy
|
||||
'acr_comment' => wfMessage( 'confirmaccount-autorej' )->inContentLanguage()->text(),
|
||||
'acr_deleted' => 1 ),
|
||||
array( "acr_rejected IS NULL",
|
||||
"acr_registration < {$encCutoff}",
|
||||
"acr_held < {$encCutoff} OR acr_held IS NULL" ),
|
||||
__METHOD__
|
||||
);
|
||||
|
||||
# Clear cache for notice of how many account requests there are
|
||||
self::clearAccountRequestCountCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag a user's email as confirmed in the db
|
||||
*
|
||||
* @param sring $name
|
||||
*/
|
||||
public static function confirmEmail( $name ) {
|
||||
$dbw = wfGetDB( DB_MASTER );
|
||||
$dbw->update( 'account_requests',
|
||||
array( 'acr_email_authenticated' => $dbw->timestamp() ),
|
||||
array( 'acr_name' => $name ),
|
||||
__METHOD__ );
|
||||
# Clear cache for notice of how many account requests there are
|
||||
self::clearAccountRequestCountCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate and store a new e-mail confirmation token, and return
|
||||
* the URL the user can use to confirm.
|
||||
* @param string $token
|
||||
* @return string
|
||||
*/
|
||||
public static function confirmationTokenUrl( $token ) {
|
||||
$title = SpecialPage::getTitleFor( 'RequestAccount' );
|
||||
return $title->getFullUrl( array(
|
||||
'action' => 'confirmemail',
|
||||
'wpEmailToken' => $token
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate, store, and return a new e-mail confirmation code.
|
||||
* A hash (unsalted since it's used as a key) is stored.
|
||||
* @param User $user
|
||||
* @param string $expiration
|
||||
* @return string
|
||||
*/
|
||||
public static function getConfirmationToken( $user, &$expiration ) {
|
||||
global $wgConfirmAccountRejectAge;
|
||||
|
||||
$expires = time() + $wgConfirmAccountRejectAge;
|
||||
$expiration = wfTimestamp( TS_MW, $expires );
|
||||
$token = $user->generateToken( $user->getName() . $user->getEmail() . $expires );
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a new e-mail confirmation token and send a confirmation
|
||||
* mail to the user's given address.
|
||||
*
|
||||
* @param User $user
|
||||
* @param string $ip User IP address
|
||||
* @param string $token
|
||||
* @param string $expiration
|
||||
* @return true|Status True on success, a Status object on failure.
|
||||
*/
|
||||
public static function sendConfirmationMail( User $user, $ip, $token, $expiration ) {
|
||||
global $wgContLang;
|
||||
|
||||
$url = self::confirmationTokenUrl( $token );
|
||||
$lang = $user->getOption( 'language' );
|
||||
return $user->sendMail(
|
||||
wfMessage( 'requestaccount-email-subj' )->inLanguage( $lang )->text(),
|
||||
wfMessage( 'requestaccount-email-body',
|
||||
$ip,
|
||||
$user->getName(),
|
||||
$url,
|
||||
$wgContLang->timeanddate( $expiration, false ) ,
|
||||
$wgContLang->date( $expiration, false ) ,
|
||||
$wgContLang->time( $expiration, false )
|
||||
)->inLanguage( $lang )->text()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a request name from an email confirmation token
|
||||
*
|
||||
* @param $code string
|
||||
* @return string|false
|
||||
*/
|
||||
public static function requestNameFromEmailToken( $code ) {
|
||||
$dbr = wfGetDB( DB_SLAVE );
|
||||
return $dbr->selectField( 'account_requests',
|
||||
'acr_name',
|
||||
array(
|
||||
'acr_email_token' => md5( $code ),
|
||||
'acr_email_token_expires > ' . $dbr->addQuotes( $dbr->timestamp() ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of account requests for a request type
|
||||
* @param $type int
|
||||
* @return Array Assosiative array with 'open', 'held', 'type' keys mapping to integers
|
||||
*/
|
||||
public static function getOpenRequestCount( $type ) {
|
||||
$dbr = wfGetDB( DB_SLAVE );
|
||||
$open = (int)$dbr->selectField( 'account_requests', 'COUNT(*)',
|
||||
array( 'acr_type' => $type, 'acr_deleted' => 0, 'acr_held IS NULL' ),
|
||||
__METHOD__
|
||||
);
|
||||
$held = (int)$dbr->selectField( 'account_requests', 'COUNT(*)',
|
||||
array( 'acr_type' => $type, 'acr_deleted' => 0, 'acr_held IS NOT NULL' ),
|
||||
__METHOD__
|
||||
);
|
||||
$rej = (int)$dbr->selectField( 'account_requests', 'COUNT(*)',
|
||||
array( 'acr_type' => $type, 'acr_deleted' => 1, 'acr_user != 0' ),
|
||||
__METHOD__
|
||||
);
|
||||
return array( 'open' => $open, 'held' => $held, 'rejected' => $rej );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of open email-confirmed account requests for a request type
|
||||
* @param $type int|string A request type or '*' for all
|
||||
* @return int
|
||||
*/
|
||||
public static function getOpenEmailConfirmedCount( $type = '*' ) {
|
||||
global $wgMemc;
|
||||
|
||||
# Check cached results
|
||||
$key = wfMemcKey( 'confirmaccount', 'econfopencount', $type );
|
||||
$count = $wgMemc->get( $key );
|
||||
# Only show message if there are any such requests
|
||||
if ( $count === false ) {
|
||||
$conds = array(
|
||||
'acr_deleted' => 0, // not rejected
|
||||
'acr_held IS NULL', // nor held
|
||||
'acr_email_authenticated IS NOT NULL' ); // email confirmed
|
||||
if ( $type !== '*' ) {
|
||||
$conds['acr_type'] = (int)$type;
|
||||
}
|
||||
$dbw = wfGetDB( DB_MASTER );
|
||||
$count = (int)$dbw->selectField( 'account_requests', 'COUNT(*)', $conds, __METHOD__ );
|
||||
# Cache results (invalidated on change )
|
||||
$wgMemc->set( $key, $count, 3600 * 24 * 7 );
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear account request cache
|
||||
* @return void
|
||||
*/
|
||||
public static function clearAccountRequestCountCache() {
|
||||
global $wgAccountRequestTypes, $wgMemc;
|
||||
|
||||
$types = array_keys( $wgAccountRequestTypes );
|
||||
$types[] = '*'; // "all" types count
|
||||
foreach ( $types as $type ) {
|
||||
$key = wfMemcKey( 'confirmaccount', 'econfopencount', $type );
|
||||
$wgMemc->delete( $key );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that it's ok to include the uploaded file
|
||||
*
|
||||
* @param string $tmpfile the full path of the temporary file to verify
|
||||
* @param string $extension The filename extension that the file is to be served with
|
||||
* @return Status object
|
||||
*/
|
||||
public static function verifyAttachment( $tmpfile, $extension ) {
|
||||
global $wgVerifyMimeType, $wgMimeTypeBlacklist;
|
||||
|
||||
$magic =& MimeMagic::singleton(); // magically determine mime type
|
||||
$mime = $magic->guessMimeType( $tmpfile, false );
|
||||
# check mime type, if desired
|
||||
if ( $wgVerifyMimeType ) {
|
||||
wfDebug ( "\n\nmime: <$mime> extension: <$extension>\n\n" );
|
||||
# Check mime type against file extension
|
||||
if ( !UploadBase::verifyExtension( $mime, $extension ) ) {
|
||||
return Status::newFatal( 'uploadcorrupt' );
|
||||
}
|
||||
# Check mime type blacklist
|
||||
if ( isset( $wgMimeTypeBlacklist ) && !is_null( $wgMimeTypeBlacklist )
|
||||
&& self::checkFileExtension( $mime, $wgMimeTypeBlacklist ) ) {
|
||||
return Status::newFatal( 'filetype-badmime', $mime );
|
||||
}
|
||||
}
|
||||
wfDebug( __METHOD__ . ": all clear; passing.\n" );
|
||||
return Status::newGood();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform case-insensitive match against a list of file extensions.
|
||||
* Returns true if the extension is in the list.
|
||||
*
|
||||
* @param string $ext
|
||||
* @param array $list
|
||||
* @return bool
|
||||
*/
|
||||
protected static function checkFileExtension( $ext, $list ) {
|
||||
return in_array( strtolower( $ext ), $list );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text to add to this users page for describing editing topics
|
||||
* for each "area" a user can be in, as defined in MediaWiki:requestaccount-areas.
|
||||
*
|
||||
* @return Array Associative mapping of the format:
|
||||
* (name => ('project' => x, 'userText' => y, 'grpUserText' => (request type => z)))
|
||||
* Any of the ultimate values can be the empty string
|
||||
*/
|
||||
public static function getUserAreaConfig() {
|
||||
static $res; // process cache
|
||||
if ( $res !== null ) {
|
||||
return $res;
|
||||
}
|
||||
$res = array();
|
||||
// Message describing the areas a user can be interested in, the corresponding wiki page,
|
||||
// and any text that is automatically appended to the userpage on account acceptance.
|
||||
// Format is <name> | <wikipage> [| <text for all>] [| <text group0>] [| <text group1>] ...
|
||||
$msg = wfMessage( 'requestaccount-areas' )->inContentLanguage();
|
||||
if ( $msg->exists() ) {
|
||||
$areas = explode( "\n*", "\n" . $msg->text() );
|
||||
foreach ( $areas as $n => $area ) {
|
||||
$set = explode( "|", $area );
|
||||
if ( count( $set ) >= 2 ) {
|
||||
$name = trim( str_replace( '_', ' ', $set[0] ) );
|
||||
$res[$name] = array();
|
||||
|
||||
$res[$name]['project'] = trim( $set[1] ); // name => WikiProject mapping
|
||||
if ( isset( $set[2] ) ) {
|
||||
$res[$name]['userText'] = trim( $set[2] ); // userpage text for all
|
||||
} else {
|
||||
$res[$name]['userText'] = '';
|
||||
}
|
||||
|
||||
$res[$name]['grpUserText'] = array(); // userpage text for certain request types
|
||||
$categories = array_slice( $set, 3 ); // keys start from 0 now in $categories
|
||||
foreach ( $categories as $i => $cat ) {
|
||||
$res[$name]['grpUserText'][$i] = trim( $cat ); // category for group $i
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a block for this user if they are blocked from requesting accounts
|
||||
* @param User $user
|
||||
* @return Block|null
|
||||
*/
|
||||
public static function getAccountRequestBlock( User $user ) {
|
||||
global $wgAccountRequestWhileBlocked;
|
||||
|
||||
$block = false;
|
||||
# If a user cannot make accounts, don't let them request them either
|
||||
if ( !$wgAccountRequestWhileBlocked ) {
|
||||
$block = $user->isBlockedFromCreateAccount();
|
||||
}
|
||||
|
||||
return $block;
|
||||
}
|
||||
}
|
487
ConfirmAccount/backend/UserAccountRequest.php
Normal file
487
ConfirmAccount/backend/UserAccountRequest.php
Normal file
|
@ -0,0 +1,487 @@
|
|||
<?php
|
||||
|
||||
class UserAccountRequest {
|
||||
/* Initially supplied fields */
|
||||
protected $id;
|
||||
protected $name;
|
||||
protected $realName;
|
||||
protected $email;
|
||||
protected $registration;
|
||||
protected $bio;
|
||||
protected $notes;
|
||||
protected $urls;
|
||||
protected $type;
|
||||
protected $areas;
|
||||
protected $fileName;
|
||||
protected $fileStorageKey;
|
||||
protected $ip;
|
||||
protected $xff;
|
||||
protected $agent;
|
||||
protected $emailToken;
|
||||
protected $emailTokenExpires;
|
||||
/* Fields set if user later confirms email */
|
||||
protected $emailAuthTimestamp;
|
||||
/* Fields used by the admins */
|
||||
protected $deleted;
|
||||
protected $rejectedTimestamp;
|
||||
protected $heldTimestamp;
|
||||
protected $user;
|
||||
protected $comment;
|
||||
|
||||
private function __construct() {}
|
||||
|
||||
/**
|
||||
* @param $row
|
||||
* @return UserAccountRequest
|
||||
*/
|
||||
public static function newFromRow( $row ) {
|
||||
$req = new self();
|
||||
|
||||
$req->id = (int)$row->acr_id;
|
||||
$req->name = $row->acr_name;
|
||||
$req->realName = $row->acr_real_name;
|
||||
$req->email = $row->acr_email;
|
||||
$req->registration = wfTimestampOrNull( TS_MW, $row->acr_registration );
|
||||
$req->bio = $row->acr_bio;
|
||||
$req->notes = $row->acr_notes;
|
||||
$req->urls = $row->acr_urls;
|
||||
$req->type = (int)$row->acr_type;
|
||||
$req->areas = self::expandAreas( $row->acr_areas );
|
||||
$req->fileName = strlen( $row->acr_filename )
|
||||
? $row->acr_filename
|
||||
: null;
|
||||
$req->fileStorageKey = $row->acr_storage_key;
|
||||
$req->ip = $row->acr_ip;
|
||||
$req->xff = $row->acr_xff;
|
||||
$req->agent = $row->acr_agent;
|
||||
$req->emailToken = $row->acr_email_token; // MD5 of token
|
||||
$req->emailTokenExpires = wfTimestampOrNull( TS_MW, $row->acr_email_token_expires );
|
||||
$req->emailAuthTimestamp = wfTimestampOrNull( TS_MW, $row->acr_email_authenticated );
|
||||
$req->deleted = (bool)$row->acr_deleted;
|
||||
$req->rejectedTimestamp = wfTimestampOrNull( TS_MW, $row->acr_rejected );
|
||||
$req->heldTimestamp = wfTimestampOrNull( TS_MW, $row->acr_held );
|
||||
$req->user = (int)$row->acr_user;
|
||||
$req->comment = $row->acr_comment;
|
||||
|
||||
return $req;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $fields array
|
||||
* @return UserAccountRequest
|
||||
*/
|
||||
public static function newFromArray( array $fields ) {
|
||||
$req = new self();
|
||||
|
||||
$req->id = isset( $fields['id'] )
|
||||
? (int)$fields['id']
|
||||
: null; // determined on insertOn()
|
||||
$req->name = $fields['name'];
|
||||
$req->realName = $fields['real_name'];
|
||||
$req->email = $fields['email'];
|
||||
$req->registration = wfTimestampOrNull( TS_MW, $fields['registration'] );
|
||||
$req->bio = $fields['bio'];
|
||||
$req->notes = $fields['notes'];
|
||||
$req->urls = $fields['urls'];
|
||||
$req->type = (int)$fields['type'];
|
||||
$req->areas = is_string( $fields['areas'] )
|
||||
? self::expandAreas( $fields['areas'] ) // DB format
|
||||
: $fields['areas']; // already expanded
|
||||
$req->fileName = strlen( $fields['filename'] )
|
||||
? $fields['filename']
|
||||
: null;
|
||||
$req->fileStorageKey = $fields['storage_key'];
|
||||
$req->ip = $fields['ip'];
|
||||
$req->xff = $fields['xff'];
|
||||
$req->agent = $fields['agent'];
|
||||
$req->emailToken = $fields['email_token']; // MD5 of token
|
||||
$req->emailTokenExpires = wfTimestampOrNull( TS_MW, $fields['email_token_expires'] );
|
||||
// These fields are typically left to default on insertion...
|
||||
$req->emailAuthTimestamp = isset( $fields['email_authenticated'] )
|
||||
? wfTimestampOrNull( TS_MW, $fields['email_authenticated'] )
|
||||
: null;
|
||||
$req->deleted = isset( $fields['deleted'] )
|
||||
? $fields['deleted']
|
||||
: false;
|
||||
$req->rejectedTimestamp = isset( $fields['rejected'] )
|
||||
? wfTimestampOrNull( TS_MW, $fields['rejected'] )
|
||||
: null;
|
||||
$req->heldTimestamp = isset( $fields['held'] )
|
||||
? wfTimestampOrNull( TS_MW, $fields['held'] )
|
||||
: null;
|
||||
$req->user = isset( $fields['user'] )
|
||||
? (int)$fields['user']
|
||||
: 0;
|
||||
$req->comment = isset( $fields['comment'] )
|
||||
? $fields['comment']
|
||||
: '';
|
||||
|
||||
return $req;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id int
|
||||
* @param $from string|null 'dbmaster' to use DB master
|
||||
* @return UserAccountRequest|null
|
||||
*/
|
||||
public static function newFromId( $id, $from = null ) {
|
||||
$db = ( $from == 'dbmaster' )
|
||||
? wfGetDB( DB_MASTER )
|
||||
: wfGetDB( DB_SLAVE );
|
||||
$row = $db->selectRow( 'account_requests', '*', array( 'acr_id' => $id ), __METHOD__ );
|
||||
if ( !$row ) {
|
||||
return null;
|
||||
}
|
||||
return self::newFromRow( $row );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name string
|
||||
* @param $from string|null 'dbmaster' to use DB master
|
||||
* @return UserAccountRequest|null
|
||||
*/
|
||||
public static function newFromName( $name, $from = null ) {
|
||||
$db = ( $master == 'dbmaster' )
|
||||
? wfGetDB( DB_MASTER )
|
||||
: wfGetDB( DB_SLAVE );
|
||||
$row = $db->selectRow( 'account_requests', '*', array( 'acr_name' => $name ), __METHOD__ );
|
||||
if ( !$row ) {
|
||||
return null;
|
||||
}
|
||||
return self::newFromRow( $row );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getId() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return sting
|
||||
*/
|
||||
public function getRealName() {
|
||||
return $this->realName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getEmail() {
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string TS_MW timestamp
|
||||
*/
|
||||
public function getRegistration() {
|
||||
return $this->registration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBio() {
|
||||
return $this->bio;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getNotes() {
|
||||
return $this->notes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getUrls() {
|
||||
return $this->urls;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $flat string Use 'flat' to get a raw blob back
|
||||
* @return array|string Flat blob or array from expanded blob
|
||||
*/
|
||||
public function getAreas( $flat = 'expanded' ) {
|
||||
if ( $flat == 'expanded' ) {
|
||||
return $this->areas;
|
||||
} elseif ( $flat == 'flat' ) {
|
||||
return self::flattenAreas( $this->areas );
|
||||
}
|
||||
throw new MWException( 'Invalid value for $flat parameter.' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getType() {
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getFileName() {
|
||||
return $this->fileName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getFileStorageKey() {
|
||||
return $this->fileStorageKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getIP() {
|
||||
return $this->ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getXFF() {
|
||||
return $this->xff;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAgent() {
|
||||
return $this->agent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getEmailToken() {
|
||||
return $this->emailToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string TS_MW timestamp
|
||||
*/
|
||||
public function getEmailTokenExpires() {
|
||||
return $this->emailTokenExpires;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null TS_MW timestamp
|
||||
*/
|
||||
public function getEmailAuthTimestamp() {
|
||||
return $this->emailAuthTimestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool Request is deleted (either rejected or expired)
|
||||
*/
|
||||
public function isDeleted() {
|
||||
return $this->deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null TS_MW timestamp
|
||||
*/
|
||||
public function getRejectTimestamp() {
|
||||
return $this->rejectedTimestamp;
|
||||
}
|
||||
/**
|
||||
* @return string|null TS_MW timestamp
|
||||
*/
|
||||
public function getHeldTimestamp() {
|
||||
return $this->heldTimestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int User ID
|
||||
*/
|
||||
public function getHandlingUser() {
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getHandlingComment() {
|
||||
return $this->comment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to insert the request into the database
|
||||
* @return int
|
||||
*/
|
||||
public function insertOn() {
|
||||
$dbw = wfGetDB( DB_MASTER );
|
||||
# Allow for some fields to be handled automatically...
|
||||
$acr_id = is_null( $this->id )
|
||||
? $this->id
|
||||
: $dbw->nextSequenceValue( 'account_requests_acr_id_seq' );
|
||||
# Insert into pending requests...
|
||||
$dbw->insert( 'account_requests',
|
||||
array(
|
||||
'acr_id' => $acr_id,
|
||||
'acr_name' => strval( $this->name ),
|
||||
'acr_email' => strval( $this->email ),
|
||||
'acr_real_name' => strval( $this->realName ),
|
||||
'acr_registration' => $dbw->timestamp( $this->registration ),
|
||||
'acr_bio' => strval( $this->bio ),
|
||||
'acr_notes' => strval( $this->notes ),
|
||||
'acr_urls' => strval( $this->urls ),
|
||||
'acr_type' => strval( $this->type ),
|
||||
'acr_areas' => self::flattenAreas( $this->areas ),
|
||||
'acr_filename' => isset( $this->fileName )
|
||||
? $this->fileName
|
||||
: null,
|
||||
'acr_storage_key' => isset( $this->fileStorageKey )
|
||||
? $this->fileStorageKey
|
||||
: null,
|
||||
'acr_comment' => strval( $this->comment ),
|
||||
'acr_ip' => strval( $this->ip ), // for spam blocking
|
||||
'acr_xff' => strval( $this->xff ), // for spam blocking
|
||||
'acr_agent' => strval( $this->agent ), // for spam blocking
|
||||
'acr_deleted' => (int)$this->deleted,
|
||||
'acr_email_token' => strval( $this->emailToken ), // MD5 of token
|
||||
'acr_email_token_expires' => $dbw->timestamp( $this->emailTokenExpires ),
|
||||
),
|
||||
__METHOD__
|
||||
);
|
||||
$this->id = $acr_id; // set for accessors
|
||||
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark this request as rejected
|
||||
* @param $admin User
|
||||
* @param $timestamp string
|
||||
* @param $reason string
|
||||
* @return bool Success
|
||||
*/
|
||||
public function markRejected( User $admin, $timestamp, $reason = '' ) {
|
||||
$dbw = wfGetDB( DB_MASTER );
|
||||
$dbw->update( 'account_requests',
|
||||
array(
|
||||
'acr_rejected' => $dbw->timestamp( $timestamp ),
|
||||
'acr_user' => $admin->getID(),
|
||||
'acr_comment' => $reason,
|
||||
'acr_deleted' => 1 ),
|
||||
array( 'acr_id' => $this->id, 'acr_deleted' => 0 ),
|
||||
__METHOD__
|
||||
);
|
||||
return ( $dbw->affectedRows() > 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark this request as held
|
||||
* @param $admin User
|
||||
* @param $timestamp string
|
||||
* @param $reason string
|
||||
* @return bool Success
|
||||
*/
|
||||
public function markHeld( User $admin, $timestamp, $reason = '' ) {
|
||||
$dbw = wfGetDB( DB_MASTER );
|
||||
$dbw->update( 'account_requests',
|
||||
array(
|
||||
'acr_held' => $dbw->timestamp( $timestamp ),
|
||||
'acr_user' => $admin->getID(),
|
||||
'acr_comment' => $reason ),
|
||||
array( 'acr_id' => $this->id, 'acr_held IS NULL', 'acr_deleted' => 0 ),
|
||||
__METHOD__
|
||||
);
|
||||
return ( $dbw->affectedRows() > 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @throws MWException
|
||||
*/
|
||||
public function remove() {
|
||||
if ( !$this->id ) {
|
||||
throw new MWException( "Account request ID is not set." );
|
||||
}
|
||||
$dbw = wfGetDB( DB_MASTER );
|
||||
$dbw->delete( 'account_requests', array( 'acr_id' => $this->id ), __METHOD__ );
|
||||
|
||||
return ( $dbw->affectedRows() > 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to acquire a username in the request queue for insertion
|
||||
* @return bool
|
||||
*/
|
||||
public static function acquireUsername( $name ) {
|
||||
$dbw = wfGetDB( DB_MASTER );
|
||||
$conds = array( 'acr_name' => $name );
|
||||
if ( $dbw->selectField( 'account_requests', '1', $conds, __METHOD__ ) ) {
|
||||
return false; // already in use
|
||||
}
|
||||
return !$dbw->selectField( 'account_requests', '1',
|
||||
$conds, __METHOD__, array( 'FOR UPDATE' ) ); // acquire LOCK
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to acquire a e-mail address in the request queue for insertion
|
||||
* @return bool
|
||||
*/
|
||||
public static function acquireEmail( $email ) {
|
||||
$dbw = wfGetDB( DB_MASTER );
|
||||
$conds = array( 'acr_email' => $email );
|
||||
if ( $dbw->selectField( 'account_requests', '1', $conds, __METHOD__ ) ) {
|
||||
return false; // already in use
|
||||
}
|
||||
return !$dbw->selectField( 'account_requests', '1',
|
||||
$conds, __METHOD__, array( 'FOR UPDATE' ) ); // acquire LOCK
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten areas of interest array
|
||||
* Used by ConfirmAccountsPage
|
||||
* @param $areas Array
|
||||
* @todo just serialize()
|
||||
* @return string
|
||||
*/
|
||||
protected static function flattenAreas( array $areas ) {
|
||||
$flatAreas = '';
|
||||
foreach ( $areas as $area ) {
|
||||
$flatAreas .= $area . "\n";
|
||||
}
|
||||
return $flatAreas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand areas of interest to array
|
||||
* Used by ConfirmAccountsPage
|
||||
* @param $areas string
|
||||
* @todo just unserialize()
|
||||
* @return Array
|
||||
*/
|
||||
public static function expandAreas( $areas ) {
|
||||
$list = explode( "\n", $areas );
|
||||
foreach ( $list as $n => $item ) {
|
||||
$list[$n] = trim( str_replace( ' ', '_', $item ) );
|
||||
}
|
||||
unset( $list[count( $list ) - 1] );
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get path relative to zone for an account request attachment file.
|
||||
* This assures compatibility with the old FileStore sytem.
|
||||
* @param $key string File storage key
|
||||
* @return string
|
||||
*/
|
||||
public static function relPathFromKey( $key ) {
|
||||
return "{$key[0]}/{$key[0]}{$key[1]}/{$key[0]}{$key[1]}{$key[2]}/{$key}";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
/**
|
||||
* Class containing updater functions for a ConfirmAccount environment
|
||||
*/
|
||||
class ConfirmAccountUpdaterHooks {
|
||||
|
||||
/**
|
||||
* @param DatabaseUpdater $updater
|
||||
* @return bool
|
||||
*/
|
||||
public static function addSchemaUpdates( DatabaseUpdater $updater ) {
|
||||
$base = dirname( __FILE__ );
|
||||
if ( $updater->getDB()->getType() == 'mysql' ) {
|
||||
$base = "$base/mysql";
|
||||
|
||||
$updater->addExtensionTable( 'account_requests', "$base/ConfirmAccount.sql" );
|
||||
$updater->addExtensionField( 'account_requests', 'acr_filename', "$base/patch-acr_filename.sql" );
|
||||
$updater->addExtensionTable( 'account_credentials', "$base/patch-account_credentials.sql" );
|
||||
$updater->addExtensionField( 'account_requests', 'acr_areas', "$base/patch-acr_areas.sql" );
|
||||
$updater->addExtensionIndex( 'account_requests', 'acr_email', "$base/patch-email-index.sql" );
|
||||
$updater->addExtensionField( 'account_requests', 'acr_agent', "$base/patch-acr_agent.sql" );
|
||||
} elseif ( $updater->getDB()->getType() == 'postgres' ) {
|
||||
$base = "$base/postgres";
|
||||
|
||||
$updater->addExtensionUpdate( array( 'addTable', 'account_requests', "$base/ConfirmAccount.pg.sql", true ) );
|
||||
$updater->addExtensionUpdate( array( 'addPgField', 'account_requests', 'acr_held', "TIMESTAMPTZ" ) );
|
||||
$updater->addExtensionUpdate( array( 'addPgField', 'account_requests', 'acr_filename', "TEXT" ) );
|
||||
$updater->addExtensionUpdate( array( 'addPgField', 'account_requests', 'acr_storage_key', "TEXT" ) );
|
||||
$updater->addExtensionUpdate( array( 'addPgField', 'account_requests', 'acr_comment', "TEXT NOT NULL DEFAULT ''" ) );
|
||||
$updater->addExtensionUpdate( array( 'addPgField', 'account_requests', 'acr_type', "INTEGER NOT NULL DEFAULT 0" ) );
|
||||
$updater->addExtensionUpdate( array( 'addTable', 'account_credentials', "$base/patch-account_credentials.sql", true ) );
|
||||
$updater->addExtensionUpdate( array( 'addPgField', 'account_requests', 'acr_areas', "TEXT" ) );
|
||||
$updater->addExtensionUpdate( array( 'addPgField', 'account_credentials', 'acd_areas', "TEXT" ) );
|
||||
$updater->addExtensionUpdate( array( 'addIndex', 'account_requests', 'acr_email', "$base/patch-email-index.sql", true ) );
|
||||
$updater->addExtensionUpdate( array( 'addPgField', 'account_requests', 'acr_agent', "$base/patch-acr_agent.sql", true ) );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
113
ConfirmAccount/backend/schema/mysql/ConfirmAccount.sql
Normal file
113
ConfirmAccount/backend/schema/mysql/ConfirmAccount.sql
Normal file
|
@ -0,0 +1,113 @@
|
|||
-- (c) Aaron Schulz, 2007
|
||||
|
||||
-- Table structure for table `Confirm account`
|
||||
-- Replace /*$wgDBprefix*/ with the proper prefix
|
||||
|
||||
-- This stores all of our reviews,
|
||||
-- the corresponding tags are stored in the tag table
|
||||
CREATE TABLE IF NOT EXISTS /*_*/account_requests (
|
||||
acr_id int unsigned NOT NULL auto_increment PRIMARY KEY,
|
||||
-- Usernames must be unique, must not be in the form of
|
||||
-- an IP address. _Shouldn't_ allow slashes or case
|
||||
-- conflicts. Spaces are allowed, and are _not_ converted
|
||||
-- to underscores like titles. See the User::newFromName() for
|
||||
-- the specific tests that usernames have to pass.
|
||||
acr_name varchar(255) binary NOT NULL default '',
|
||||
-- Optional 'real name' to be displayed in credit listings
|
||||
acr_real_name varchar(255) binary NOT NULL default '',
|
||||
-- Note: email should be restricted, not public info.
|
||||
-- Same with passwords.
|
||||
acr_email tinytext NOT NULL,
|
||||
-- Initially NULL; when a user's e-mail address has been
|
||||
-- validated by returning with a mailed token, this is
|
||||
-- set to the current timestamp.
|
||||
acr_email_authenticated varbinary(14) default NULL,
|
||||
-- Randomly generated token created when the e-mail address
|
||||
-- is set and a confirmation test mail sent.
|
||||
acr_email_token binary(32),
|
||||
-- Expiration date for the user_email_token
|
||||
acr_email_token_expires varbinary(14),
|
||||
-- A little about this user
|
||||
acr_bio mediumblob NOT NULL,
|
||||
-- Private info for reviewers to look at when considering request
|
||||
acr_notes mediumblob NOT NULL,
|
||||
-- Links to recognize/identify this user, CSV, may not be public
|
||||
acr_urls mediumblob NOT NULL,
|
||||
-- IP address
|
||||
acr_ip VARCHAR(255) NULL default '',
|
||||
acr_xff VARCHAR(255) NULL default '',
|
||||
-- User-Agent header
|
||||
acr_agent VARCHAR(255) NULL default '',
|
||||
-- Name of attached file (.pdf,.doc,.txt etc...)
|
||||
acr_filename VARCHAR(255) NULL,
|
||||
acr_storage_key VARCHAR(64) NULL,
|
||||
-- Prospective account access level
|
||||
acr_type tinyint(255) unsigned NOT NULL default 0,
|
||||
-- Areas of interest
|
||||
acr_areas mediumblob NOT NULL,
|
||||
|
||||
-- Timestamp of account registration.
|
||||
acr_registration varbinary(14) NOT NULL,
|
||||
|
||||
-- Flag for rejected accounts
|
||||
acr_deleted bool NOT NULL,
|
||||
-- Time of rejection (if rejected)
|
||||
acr_rejected varbinary(14),
|
||||
-- Time request was put on hold (if held)
|
||||
acr_held varbinary(14),
|
||||
-- The user who rejected/held it
|
||||
acr_user int unsigned NOT NULL default 0,
|
||||
-- Reason
|
||||
acr_comment varchar(255) NOT NULL default ''
|
||||
) /*$wgDBTableOptions*/;
|
||||
|
||||
CREATE UNIQUE INDEX /*i*/acr_name ON /*_*/account_requests (acr_name);
|
||||
CREATE UNIQUE INDEX /*i*/acr_email ON /*_*/account_requests (acr_email(255));
|
||||
CREATE INDEX /*i*/acr_email_token ON /*_*/account_requests (acr_email_token);
|
||||
CREATE INDEX /*i*/acr_type_del_reg ON /*_*/account_requests (acr_type,acr_deleted,acr_registration);
|
||||
|
||||
-- This stores all of credential information
|
||||
-- When accounts are confirmed, the identity info goes here
|
||||
CREATE TABLE IF NOT EXISTS /*_*/account_credentials (
|
||||
-- Revision ID #
|
||||
acd_id int unsigned NOT NULL auto_increment PRIMARY KEY,
|
||||
-- Foreign key to user.user_id
|
||||
acd_user_id int unsigned NOT NULL,
|
||||
-- Optional 'real name' to be displayed in credit listings
|
||||
acd_real_name varchar(255) binary NOT NULL default '',
|
||||
-- Note: email should be restricted, not public info.
|
||||
-- Same with passwords.
|
||||
acd_email tinytext NOT NULL,
|
||||
-- Initially NULL; when a user's e-mail address has been
|
||||
-- validated by returning with a mailed token, this is
|
||||
-- set to the current timestamp.
|
||||
acd_email_authenticated varbinary(14) default NULL,
|
||||
-- A little about this user
|
||||
acd_bio mediumblob NOT NULL,
|
||||
-- Private info for reviewers to look at when considering request
|
||||
acd_notes mediumblob NOT NULL,
|
||||
-- Links to recognize/identify this user, CSV, may not be public
|
||||
acd_urls mediumblob NOT NULL,
|
||||
-- IP address
|
||||
acd_ip VARCHAR(255) NULL default '',
|
||||
acd_xff VARCHAR(255) NULL default '',
|
||||
-- User-Agent header
|
||||
acd_agent VARCHAR(255) NULL default '',
|
||||
-- Name of attached file (.pdf,.doc,.txt etc...)
|
||||
acd_filename VARCHAR(255) NULL,
|
||||
acd_storage_key VARCHAR(64) NULL,
|
||||
-- Areas of interest
|
||||
acd_areas mediumblob NOT NULL,
|
||||
|
||||
-- Timestamp of account registration.
|
||||
acd_registration varbinary(14) NOT NULL,
|
||||
|
||||
-- Timestamp of acceptance
|
||||
acd_accepted varbinary(14),
|
||||
-- The user who accepted it
|
||||
acd_user int unsigned NOT NULL default 0,
|
||||
-- Reason given in email
|
||||
acd_comment varchar(255) NOT NULL default ''
|
||||
) /*$wgDBTableOptions*/;
|
||||
|
||||
CREATE UNIQUE INDEX /*i*/acd_user_id ON /*_*/account_credentials (acd_user_id,acd_id);
|
|
@ -0,0 +1,49 @@
|
|||
-- (c) Aaron Schulz, 2007
|
||||
|
||||
ALTER TABLE /*$wgDBprefix*/account_requests
|
||||
ADD acr_type tinyint(255) unsigned NOT NULL default 0,
|
||||
DROP INDEX acr_deleted_reg,
|
||||
ADD INDEX acr_type_del_reg (acr_type,acr_deleted,acr_registration);
|
||||
|
||||
-- This stores all of credential information
|
||||
-- When accounts are confirmed, the identity info goes here
|
||||
CREATE TABLE IF NOT EXISTS /*_*/account_credentials (
|
||||
-- Revision ID #
|
||||
acd_id int unsigned NOT NULL auto_increment PRIMARY KEY,
|
||||
-- Foreign key to user.user_id
|
||||
acd_user_id int unsigned NOT NULL,
|
||||
-- Optional 'real name' to be displayed in credit listings
|
||||
acd_real_name varchar(255) binary NOT NULL default '',
|
||||
-- Note: email should be restricted, not public info.
|
||||
-- Same with passwords.
|
||||
acd_email tinytext NOT NULL,
|
||||
-- Initially NULL; when a user's e-mail address has been
|
||||
-- validated by returning with a mailed token, this is
|
||||
-- set to the current timestamp.
|
||||
acd_email_authenticated varbinary(14) default NULL,
|
||||
-- A little about this user
|
||||
acd_bio mediumblob NOT NULL,
|
||||
-- Private info for reviewers to look at when considering request
|
||||
acd_notes mediumblob NOT NULL,
|
||||
-- Links to recognize/identify this user, CSV, may not be public
|
||||
acd_urls mediumblob NOT NULL,
|
||||
-- IP address
|
||||
acd_ip VARCHAR(255) NULL default '',
|
||||
-- Name of attached file (.pdf,.doc,.txt etc...)
|
||||
acd_filename VARCHAR(255) NULL,
|
||||
acd_storage_key VARCHAR(64) NULL,
|
||||
-- Areas of interest
|
||||
acd_areas mediumblob NOT NULL,
|
||||
|
||||
-- Timestamp of account registration.
|
||||
acd_registration varbinary(14) NOT NULL,
|
||||
|
||||
-- Timestamp of acceptance
|
||||
acd_accepted varbinary(14),
|
||||
-- The user who accepted it
|
||||
acd_user int unsigned NOT NULL default 0,
|
||||
-- Reason given in email
|
||||
acd_comment varchar(255) NOT NULL default ''
|
||||
) /*$wgDBTableOptions*/;
|
||||
|
||||
CREATE UNIQUE INDEX /*i*/acd_user_id ON /*_*/account_credentials (acd_user_id,acd_id);
|
9
ConfirmAccount/backend/schema/mysql/patch-acr_agent.sql
Normal file
9
ConfirmAccount/backend/schema/mysql/patch-acr_agent.sql
Normal file
|
@ -0,0 +1,9 @@
|
|||
-- (c) Aaron Schulz, 2007
|
||||
|
||||
ALTER TABLE /*$wgDBprefix*/account_requests
|
||||
ADD acr_xff VARCHAR(255) NULL default '',
|
||||
ADD acr_agent VARCHAR(255) NULL default '';
|
||||
|
||||
ALTER TABLE /*$wgDBprefix*/account_credentials
|
||||
ADD acd_xff VARCHAR(255) NULL default '',
|
||||
ADD acd_agent VARCHAR(255) NULL default '';
|
7
ConfirmAccount/backend/schema/mysql/patch-acr_areas.sql
Normal file
7
ConfirmAccount/backend/schema/mysql/patch-acr_areas.sql
Normal file
|
@ -0,0 +1,7 @@
|
|||
-- (c) Aaron Schulz, 2007
|
||||
|
||||
ALTER TABLE /*$wgDBprefix*/account_requests
|
||||
ADD acr_areas mediumblob NOT NULL;
|
||||
|
||||
ALTER TABLE /*$wgDBprefix*/account_credentials
|
||||
ADD acd_areas mediumblob NOT NULL;
|
|
@ -0,0 +1,7 @@
|
|||
-- (c) Aaron Schulz, 2007
|
||||
|
||||
ALTER TABLE /*$wgDBprefix*/account_requests
|
||||
ADD acr_filename VARCHAR(255) NULL,
|
||||
ADD acr_storage_key VARCHAR(64) NULL,
|
||||
ADD acr_held binary(14),
|
||||
ADD acr_comment VARCHAR(255) NULL;
|
|
@ -0,0 +1,4 @@
|
|||
-- (c) Aaron Schulz, 2007
|
||||
|
||||
ALTER TABLE /*$wgDBprefix*/account_requests
|
||||
ADD UNIQUE INDEX acr_email(acr_email(255));
|
62
ConfirmAccount/backend/schema/postgres/ConfirmAccount.pg.sql
Normal file
62
ConfirmAccount/backend/schema/postgres/ConfirmAccount.pg.sql
Normal file
|
@ -0,0 +1,62 @@
|
|||
-- (c) Aaron Schulz, 2007
|
||||
|
||||
-- Postgres schema for Confirm Account extension
|
||||
|
||||
BEGIN;
|
||||
|
||||
CREATE SEQUENCE account_requests_acr_id_seq;
|
||||
CREATE TABLE account_requests (
|
||||
acr_id INTEGER PRIMARY KEY NOT NULL DEFAULT nextval('account_requests_acr_id_seq'),
|
||||
acr_name TEXT NOT NULL UNIQUE,
|
||||
acr_real_name TEXT,
|
||||
acr_email TEXT,
|
||||
acr_email_token CHAR(32),
|
||||
acr_email_token_expires TIMESTAMPTZ,
|
||||
acr_email_authenticated TIMESTAMPTZ,
|
||||
acr_registration TIMESTAMPTZ,
|
||||
acr_bio TEXT,
|
||||
acr_notes TEXT,
|
||||
acr_urls TEXT,
|
||||
acr_ip CIDR,
|
||||
acr_xff TEXT,
|
||||
acr_agent TEXT,
|
||||
acr_filename TEXT,
|
||||
acr_storage_key TEXT,
|
||||
acr_type INTEGER NOT NULL DEFAULT 0,
|
||||
acr_areas TEXT,
|
||||
acr_deleted BOOL NOT NULL DEFAULT 'false',
|
||||
acr_rejected TIMESTAMPTZ,
|
||||
acr_held TIMESTAMPTZ,
|
||||
acr_user INTEGER REFERENCES mwuser(user_id) ON DELETE SET NULL,
|
||||
acr_comment TEXT NOT NULL DEFAULT ''
|
||||
);
|
||||
|
||||
CREATE INDEX acr_type_del_reg ON account_requests (acr_type,acr_deleted,acr_registration);
|
||||
CREATE INDEX acr_email_token ON account_requests (acr_email_token);
|
||||
CREATE UNIQUE INDEX acr_email ON account_requests (acr_email);
|
||||
|
||||
CREATE SEQUENCE account_credentials_acd_id_seq;
|
||||
CREATE TABLE account_credentials (
|
||||
acd_id INTEGER NOT NULL DEFAULT nextval('account_credentials_acd_id_seq'),
|
||||
acd_user_id INTEGER,
|
||||
acd_real_name TEXT,
|
||||
acd_email TEXT,
|
||||
acd_email_authenticated TIMESTAMPTZ,
|
||||
acd_registration TIMESTAMPTZ,
|
||||
acd_bio TEXT,
|
||||
acd_notes TEXT,
|
||||
acd_urls TEXT,
|
||||
acd_ip CIDR,
|
||||
acd_xff TEXT,
|
||||
acd_agent TEXT,
|
||||
acd_filename TEXT,
|
||||
acd_storage_key TEXT,
|
||||
acd_areas TEXT,
|
||||
acd_accepted TIMESTAMPTZ,
|
||||
acd_user INTEGER REFERENCES mwuser(user_id) ON DELETE SET NULL,
|
||||
acd_comment TEXT NOT NULL DEFAULT '',
|
||||
PRIMARY KEY (acd_id, acd_user_id)
|
||||
);
|
||||
CREATE UNIQUE INDEX acd_id_index ON account_credentials (acd_id);
|
||||
|
||||
COMMIT;
|
|
@ -0,0 +1,28 @@
|
|||
-- (c) Aaron Schulz, 2007
|
||||
|
||||
BEGIN;
|
||||
|
||||
CREATE SEQUENCE account_credentials_acd_id_seq;
|
||||
CREATE TABLE account_credentials (
|
||||
acd_id INTEGER NOT NULL DEFAULT nextval('account_credentials_acd_id_seq'),
|
||||
acd_user_id INTEGER,
|
||||
acd_real_name TEXT,
|
||||
acd_email TEXT,
|
||||
acd_email_authenticated TIMESTAMPTZ,
|
||||
acd_registration TIMESTAMPTZ,
|
||||
acd_bio TEXT,
|
||||
acd_notes TEXT,
|
||||
acd_urls TEXT,
|
||||
acd_ip CIDR,
|
||||
acd_filename TEXT,
|
||||
acd_storage_key TEXT,
|
||||
acd_areas TEXT,
|
||||
acd_accepted TIMESTAMPTZ,
|
||||
acd_user INTEGER REFERENCES mwuser(user_id) ON DELETE SET NULL,
|
||||
acd_comment TEXT NOT NULL DEFAULT '',
|
||||
PRIMARY KEY (acd_id, acd_user_id)
|
||||
);
|
||||
CREATE UNIQUE INDEX acd_id_index ON account_credentials (acd_id);
|
||||
|
||||
|
||||
COMMIT;
|
11
ConfirmAccount/backend/schema/postgres/patch-acr_agent.sql
Normal file
11
ConfirmAccount/backend/schema/postgres/patch-acr_agent.sql
Normal file
|
@ -0,0 +1,11 @@
|
|||
BEGIN;
|
||||
|
||||
ALTER TABLE account_requests
|
||||
ADD acr_xff TEXT,
|
||||
ADD acr_agent TEXT;
|
||||
|
||||
ALTER TABLE account_credentials
|
||||
ADD acd_xff TEXT,
|
||||
ADD acd_agent TEXT;
|
||||
|
||||
COMMIT;
|
|
@ -0,0 +1,5 @@
|
|||
BEGIN;
|
||||
|
||||
CREATE UNIQUE INDEX acr_email ON account_requests (acr_email);
|
||||
|
||||
COMMIT;
|
450
ConfirmAccount/business/AccountConfirmSubmission.php
Normal file
450
ConfirmAccount/business/AccountConfirmSubmission.php
Normal file
|
@ -0,0 +1,450 @@
|
|||
<?php
|
||||
|
||||
class AccountConfirmSubmission {
|
||||
/* User making the confirmation */
|
||||
protected $admin;
|
||||
/** @var UserAccountRequest */
|
||||
protected $accReq;
|
||||
/* Admin-overridable name and fields filled from request form */
|
||||
protected $userName;
|
||||
protected $bio;
|
||||
protected $type;
|
||||
/** @var array */
|
||||
protected $areas;
|
||||
|
||||
protected $action;
|
||||
protected $reason;
|
||||
|
||||
public function __construct( User $admin, UserAccountRequest $accReq, array $params ) {
|
||||
$this->admin = $admin;
|
||||
$this->accountReq = $accReq;
|
||||
$this->userName = trim( $params['userName'] );
|
||||
$this->bio = trim( $params['bio'] );
|
||||
$this->type = $params['type'];
|
||||
$this->areas = $params['areas'];
|
||||
$this->action = $params['action'];
|
||||
$this->reason = $params['reason'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to validate and submit this data to the DB
|
||||
* @param $context IContextSource
|
||||
* @return array( true or error key string, html error msg or null )
|
||||
*/
|
||||
public function submit( IContextSource $context ) {
|
||||
# Make sure that basic permissions are checked
|
||||
if ( !$this->admin->getID() || !$this->admin->isAllowed( 'confirmaccount' ) ) {
|
||||
return array( 'accountconf_permission_denied', $context->msg( 'badaccess-group0' )->escaped() );
|
||||
} elseif ( wfReadOnly() ) {
|
||||
return array( 'accountconf_readonly', $context->msg( 'badaccess-group0' )->escaped() );
|
||||
}
|
||||
if ( $this->action === 'spam' ) {
|
||||
return $this->spamRequest( $context );
|
||||
} elseif ( $this->action === 'reject' ) {
|
||||
return $this->rejectRequest( $context );
|
||||
} elseif ( $this->action === 'hold' ) {
|
||||
return $this->holdRequest( $context );
|
||||
} elseif ( $this->action === 'accept' ) {
|
||||
return $this->acceptRequest( $context );
|
||||
} else {
|
||||
return array( 'accountconf_bad_action', $context->msg( 'confirmaccount-badaction' )->escaped() );
|
||||
}
|
||||
}
|
||||
|
||||
protected function spamRequest( IContextSource $context ) {
|
||||
$dbw = wfGetDB( DB_MASTER );
|
||||
$dbw->begin();
|
||||
|
||||
$ok = $this->accountReq->markRejected( $this->admin, wfTimestampNow(), '' );
|
||||
if ( $ok ) {
|
||||
# Clear cache for notice of how many account requests there are
|
||||
ConfirmAccount::clearAccountRequestCountCache();
|
||||
}
|
||||
|
||||
$dbw->commit();
|
||||
return array( true, null );
|
||||
}
|
||||
|
||||
protected function rejectRequest( IContextSource $context ) {
|
||||
$dbw = wfGetDB( DB_MASTER );
|
||||
$dbw->begin();
|
||||
|
||||
$ok = $this->accountReq->markRejected( $this->admin, wfTimestampNow(), $this->reason );
|
||||
if ( $ok ) {
|
||||
/*
|
||||
# Make proxy user to email a rejection message :(
|
||||
$u = User::newFromName( $this->accountReq->getName(), false );
|
||||
$u->setEmail( $this->accountReq->getEmail() );
|
||||
# Send out a rejection email...
|
||||
if ( $this->reason != '' ) {
|
||||
$emailBody = $context->msg( 'confirmaccount-email-body4',
|
||||
$u->getName(), $this->reason )->inContentLanguage()->text();
|
||||
} else {
|
||||
$emailBody = $context->msg( 'confirmaccount-email-body3',
|
||||
$u->getName() )->inContentLanguage()->text();
|
||||
}
|
||||
$result = $u->sendMail(
|
||||
$context->msg( 'confirmaccount-email-subj' )->inContentLanguage()->text(),
|
||||
$emailBody
|
||||
);
|
||||
if ( !$result->isOk() ) {
|
||||
$dbw->rollback();
|
||||
return array( 'accountconf_mailerror',
|
||||
$context->msg( 'mailerror' )->rawParams( $context->getOutput()->parse( $result->getWikiText() ) )->text() );
|
||||
}
|
||||
# Clear cache for notice of how many account requests there are
|
||||
*/
|
||||
ConfirmAccount::clearAccountRequestCountCache();
|
||||
}
|
||||
|
||||
$dbw->commit();
|
||||
return array( true, null );
|
||||
}
|
||||
|
||||
protected function holdRequest( IContextSource $context ) {
|
||||
# Make proxy user to email a message
|
||||
$u = User::newFromName( $this->accountReq->getName(), false );
|
||||
$u->setEmail( $this->accountReq->getEmail() );
|
||||
|
||||
# Pointless without a summary...
|
||||
if ( $this->reason == '' ) {
|
||||
return array( 'accountconf_needreason', $context->msg( 'confirmaccount-needreason' )->escaped() );
|
||||
}
|
||||
|
||||
$dbw = wfGetDB( DB_MASTER );
|
||||
$dbw->begin();
|
||||
|
||||
# If not already held or deleted, mark as held
|
||||
$ok = $this->accountReq->markHeld( $this->admin, wfTimestampNow(), $this->reason );
|
||||
if ( !$ok ) { // already held or deleted?
|
||||
$dbw->rollback();
|
||||
return array( 'accountconf_canthold', $context->msg( 'confirmaccount-canthold' )->escaped() );
|
||||
}
|
||||
|
||||
# Send out a request hold email...
|
||||
$result = $u->sendMail(
|
||||
$context->msg( 'confirmaccount-email-subj' )->inContentLanguage()->text(),
|
||||
$context->msg( 'confirmaccount-email-body5', $u->getName(), $this->reason )->inContentLanguage()->text()
|
||||
);
|
||||
if ( !$result->isOk() ) {
|
||||
$dbw->rollback();
|
||||
return array( 'accountconf_mailerror',
|
||||
$context->msg( 'mailerror' )->rawParams( $context->getOutput()->parse( $result->getWikiText() ) )->text() );
|
||||
}
|
||||
|
||||
# Clear cache for notice of how many account requests there are
|
||||
ConfirmAccount::clearAccountRequestCountCache();
|
||||
|
||||
$dbw->commit();
|
||||
return array( true, null );
|
||||
}
|
||||
|
||||
protected function acceptRequest( IContextSource $context ) {
|
||||
global $wgAuth, $wgAccountRequestTypes, $wgConfirmAccountSaveInfo;
|
||||
global $wgConfirmAccountRequestFormItems, $wgConfirmAccountFSRepos;
|
||||
|
||||
$formConfig = $wgConfirmAccountRequestFormItems; // convience
|
||||
$accReq = $this->accountReq; // convenience
|
||||
|
||||
# Now create user and check if the name is valid
|
||||
$user = User::newFromName( $this->userName, 'creatable' );
|
||||
if ( !$user ) {
|
||||
return array( 'accountconf_invalid_name', $context->msg( 'noname' )->escaped() );
|
||||
}
|
||||
|
||||
# Check if account name is already in use
|
||||
if ( 0 != $user->idForName() || $wgAuth->userExists( $user->getName() ) ) {
|
||||
return array( 'accountconf_user_exists', $context->msg( 'userexists' )->escaped() );
|
||||
}
|
||||
|
||||
$dbw = wfGetDB( DB_MASTER );
|
||||
$dbw->begin();
|
||||
|
||||
# Make a random password
|
||||
$p = md5(strtolower($this->userName));
|
||||
|
||||
# Insert the new user into the DB...
|
||||
$tokenExpires = $accReq->getEmailTokenExpires();
|
||||
$authenticated = $accReq->getEmailAuthTimestamp();
|
||||
$params = array(
|
||||
# Set the user's real name
|
||||
'real_name' => $accReq->getRealName(),
|
||||
# Set the temporary password
|
||||
'newpassword' => User::crypt( $p ),
|
||||
# VERY important to set email now. Otherwise the user
|
||||
# will have to request a new password at the login screen...
|
||||
'email' => $accReq->getEmail(),
|
||||
# Import email address confirmation status
|
||||
'email_authenticated' => $dbw->timestampOrNull( $authenticated ),
|
||||
'email_token_expires' => $dbw->timestamp( $tokenExpires ),
|
||||
'email_token' => $accReq->getEmailToken()
|
||||
);
|
||||
$user = User::createNew( $user->getName(), $params );
|
||||
|
||||
# Grant any necessary rights (exclude blank or dummy groups)
|
||||
$group = self::getGroupFromType( $this->type );
|
||||
if ( $group != '' && $group != 'user' && $group != '*' ) {
|
||||
$user->addGroup( $group );
|
||||
}
|
||||
|
||||
$acd_id = null; // used for rollback cleanup
|
||||
# Save account request data to credentials system
|
||||
if ( $wgConfirmAccountSaveInfo ) {
|
||||
$key = $accReq->getFileStorageKey();
|
||||
# Copy any attached files to new storage group
|
||||
if ( $formConfig['CV']['enabled'] && $key ) {
|
||||
$repoOld = new FSRepo( $wgConfirmAccountFSRepos['accountreqs'] );
|
||||
$repoNew = new FSRepo( $wgConfirmAccountFSRepos['accountcreds'] );
|
||||
|
||||
$pathRel = UserAccountRequest::relPathFromKey( $key );
|
||||
$oldPath = $repoOld->getZonePath( 'public' ) . '/' . $pathRel;
|
||||
|
||||
$triplet = array( $oldPath, 'public', $pathRel );
|
||||
$status = $repoNew->storeBatch( array( $triplet ) ); // copy!
|
||||
if ( !$status->isOK() ) {
|
||||
$dbw->rollback();
|
||||
# DELETE new rows in case there was a COMMIT somewhere
|
||||
$this->acceptRequest_rollback( $dbw, $user->getId(), $acd_id );
|
||||
return array( 'accountconf_copyfailed',
|
||||
$context->getOutput()->parse( $status->getWikiText() ) );
|
||||
}
|
||||
}
|
||||
$acd_id = $dbw->nextSequenceValue( 'account_credentials_acd_id_seq' );
|
||||
# Move request data into a separate table
|
||||
$dbw->insert( 'account_credentials',
|
||||
array(
|
||||
'acd_user_id' => $user->getID(),
|
||||
'acd_real_name' => $accReq->getRealName(),
|
||||
'acd_email' => $accReq->getEmail(),
|
||||
'acd_email_authenticated' => $dbw->timestampOrNull( $authenticated ),
|
||||
'acd_bio' => $accReq->getBio(),
|
||||
'acd_notes' => $accReq->getNotes(),
|
||||
'acd_urls' => $accReq->getUrls(),
|
||||
'acd_ip' => $accReq->getIP(),
|
||||
'acd_xff' => $accReq->getXFF(),
|
||||
'acd_agent' => $accReq->getAgent(),
|
||||
'acd_filename' => $accReq->getFileName(),
|
||||
'acd_storage_key' => $accReq->getFileStorageKey(),
|
||||
'acd_areas' => $accReq->getAreas( 'flat' ),
|
||||
'acd_registration' => $dbw->timestamp( $accReq->getRegistration() ),
|
||||
'acd_accepted' => $dbw->timestamp(),
|
||||
'acd_user' => $this->admin->getID(),
|
||||
'acd_comment' => $this->reason,
|
||||
'acd_id' => $acd_id
|
||||
),
|
||||
__METHOD__
|
||||
);
|
||||
if ( is_null( $acd_id ) ) {
|
||||
$acd_id = $dbw->insertId(); // set $acd_id to ID inserted
|
||||
}
|
||||
}
|
||||
|
||||
# Add to global user login system (if there is one)
|
||||
if ( !$wgAuth->addUser( $user, $p, $accReq->getEmail(), $accReq->getRealName() ) ) {
|
||||
$dbw->rollback();
|
||||
# DELETE new rows in case there was a COMMIT somewhere
|
||||
$this->acceptRequest_rollback( $dbw, $user->getId(), $acd_id );
|
||||
return array( 'accountconf_externaldberror', $context->msg( 'externaldberror' )->escaped() );
|
||||
}
|
||||
|
||||
# OK, now remove the request from the queue
|
||||
$accReq->remove();
|
||||
|
||||
# Commit this if we make past the CentralAuth system
|
||||
# and the groups are added. Next step is sending out an
|
||||
# email, which we cannot take back...
|
||||
$dbw->commit();
|
||||
|
||||
# Prepare a temporary password email...
|
||||
if ( $this->reason != '' ) {
|
||||
$msg = "confirmaccount-email-body2-pos{$this->type}";
|
||||
# If the user is in a group and there is a welcome for that group, use it
|
||||
if ( $group && !wfEmptyMsg( $msg ) ) {
|
||||
$ebody = $context->msg( $msg, $user->getName(), $p, $this->reason )->inContentLanguage()->text();
|
||||
# Use standard if none found...
|
||||
} else {
|
||||
$ebody = $context->msg( 'confirmaccount-email-body2',
|
||||
$user->getName(), $p, $this->reason )->inContentLanguage()->text();
|
||||
}
|
||||
} else {
|
||||
$msg = "confirmaccount-email-body-pos{$this->type}";
|
||||
# If the user is in a group and there is a welcome for that group, use it
|
||||
if ( $group && !$context->msg( $msg )->isDisabled() ) {
|
||||
$ebody = $context->msg( $msg,
|
||||
$user->getName(), $p, $this->reason )->inContentLanguage()->text();
|
||||
# Use standard if none found...
|
||||
} else {
|
||||
$ebody = $context->msg( 'confirmaccount-email-body',
|
||||
$user->getName(), $p, $this->reason )->inContentLanguage()->text();
|
||||
}
|
||||
}
|
||||
|
||||
# Actually send out the email (@TODO: rollback on failure including $wgAuth)
|
||||
$result = $user->sendMail(
|
||||
$context->msg( 'confirmaccount-email-subj' )->inContentLanguage()->text(),
|
||||
$ebody
|
||||
);
|
||||
|
||||
# Update user count
|
||||
$ssUpdate = new SiteStatsUpdate( 0, 0, 0, 0, 1 );
|
||||
$ssUpdate->doUpdate();
|
||||
|
||||
# Safe to hook/log now...
|
||||
wfRunHooks( 'AddNewAccount', array( $user, false /* not by email */ ) );
|
||||
$user->addNewUserLogEntry();
|
||||
|
||||
# Clear cache for notice of how many account requests there are
|
||||
ConfirmAccount::clearAccountRequestCountCache();
|
||||
|
||||
# Delete any attached file and don't stop the whole process if this fails
|
||||
if ( $formConfig['CV']['enabled'] ) {
|
||||
$key = $accReq->getFileStorageKey();
|
||||
if ( $key ) {
|
||||
$repoOld = new FSRepo( $wgConfirmAccountFSRepos['accountreqs'] );
|
||||
$pathRel = UserAccountRequest::relPathFromKey( $key );
|
||||
$oldPath = $repoOld->getZonePath( 'public' ) . '/' . $pathRel;
|
||||
if ( file_exists( $oldPath ) ) {
|
||||
unlink( $oldPath ); // delete!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Start up the user's userpages if set to do so.
|
||||
# Will not append, so previous content will be blanked.
|
||||
$this->createUserPage( $user );
|
||||
|
||||
# Greet the new user if set to do so.
|
||||
$this->createUserTalkPage( $user );
|
||||
|
||||
return array( true, null );
|
||||
}
|
||||
|
||||
/*
|
||||
* Rollback an account acceptance *before* the request row and attachment are deleted.
|
||||
* This is mostly here for sanity in case of COMMITs triggered elsewhere.
|
||||
* http://bugs.mysql.com/bug.php?id=30767 behavoir assumed.
|
||||
* @param $dbw Database
|
||||
* @param $user_id int
|
||||
* @param $acd_id int
|
||||
* @return void
|
||||
*/
|
||||
protected function acceptRequest_rollback( DatabaseBase $dbw, $user_id, $acd_id ) {
|
||||
$dbw->begin();
|
||||
# DELETE the user in case something caused a COMMIT already somewhere.
|
||||
if ( $user_id ) {
|
||||
$dbw->delete( 'user', array( 'user_id' => $user_id ), __METHOD__ );
|
||||
$dbw->delete( 'user_groups', array( 'ug_user' => $user_id ), __METHOD__ );
|
||||
}
|
||||
# DELETE the new account_credentials row likewise.
|
||||
if ( $acd_id ) {
|
||||
$dbw->delete( 'account_credentials', array( 'acd_id' => $acd_id ), __METHOD__ );
|
||||
}
|
||||
$dbw->commit();
|
||||
}
|
||||
|
||||
protected static function getGroupFromType( $type ) {
|
||||
global $wgAccountRequestTypes;
|
||||
|
||||
$group = '';
|
||||
// Format is (type => (subpage par, group key, group text))
|
||||
if ( isset( $wgAccountRequestTypes[$type][1] ) ) {
|
||||
$group = $wgAccountRequestTypes[$type][1];
|
||||
}
|
||||
|
||||
return $group;
|
||||
}
|
||||
|
||||
protected static function getAutoTextFromType( $type ) {
|
||||
global $wgAccountRequestTypes;
|
||||
|
||||
$groupText = '';
|
||||
// Format is (type => (subpage par, group key, group text))
|
||||
if ( isset( $wgAccountRequestTypes[$type][2] ) ) {
|
||||
$groupText = $wgAccountRequestTypes[$type][2];
|
||||
}
|
||||
|
||||
return $groupText;
|
||||
}
|
||||
|
||||
protected function createUserPage( User $user ) {
|
||||
global $wgMakeUserPageFromBio, $wgAutoUserBioText;
|
||||
global $wgConfirmAccountSortkey, $wgContLang;
|
||||
|
||||
$body = ''; // page text
|
||||
|
||||
if ( $wgMakeUserPageFromBio ) {
|
||||
# Add account request bio to userpage
|
||||
$body .= $this->bio;
|
||||
# Add any automatic text for all confirmed accounts
|
||||
if ( $wgAutoUserBioText != '' ) {
|
||||
$body .= "\n\n{$wgAutoUserBioText}";
|
||||
}
|
||||
}
|
||||
|
||||
# Add any automatic text for confirmed accounts of this type
|
||||
$autoText = self::getAutoTextFromType( $this->type );
|
||||
if ( $autoText != '' ) {
|
||||
$body .= "\n\n{$autoText}";
|
||||
}
|
||||
|
||||
# Add any areas of interest categories...
|
||||
foreach ( ConfirmAccount::getUserAreaConfig() as $name => $conf ) {
|
||||
if ( in_array( $name, $this->areas ) ) {
|
||||
# General userpage text for anyone with this interest
|
||||
if ( $conf['userText'] != '' ) {
|
||||
$body .= $conf['userText'];
|
||||
}
|
||||
# Message for users with this interested with the given account type
|
||||
if ( isset( $conf['grpUserText'][$this->type] )
|
||||
&& $conf['grpUserText'][$this->type] != '' )
|
||||
{
|
||||
$body .= $conf['grpUserText'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Set sortkey and use it on userpage. This can be used to
|
||||
# normalize things like firstname, lastname and so fourth.
|
||||
if ( !empty( $wgConfirmAccountSortkey ) ) {
|
||||
$sortKey = preg_replace(
|
||||
$wgConfirmAccountSortkey[0],
|
||||
$wgConfirmAccountSortkey[1],
|
||||
$user->getUserPage()->getText()
|
||||
);
|
||||
$body .= "\n{{DEFAULTSORT:{$sortKey}}}";
|
||||
# Clean up any other categories...
|
||||
$catNS = $wgContLang->getNSText( NS_CATEGORY );
|
||||
$replace = '/\[\[' . preg_quote( $catNS ) . ':([^\]]+)\]\]/i'; // [[Category:x]]
|
||||
$with = "[[{$catNS}:$1|" . str_replace( '$', '\$', $sortKey ) . "]]"; // [[Category:x|sortkey]]
|
||||
$body = preg_replace( $replace, $with, $body );
|
||||
}
|
||||
|
||||
# Create userpage!
|
||||
$article = new WikiPage( $user->getUserPage() );
|
||||
$article->doEdit(
|
||||
$body,
|
||||
wfMessage( 'confirmaccount-summary' )->inContentLanguage()->text(),
|
||||
EDIT_MINOR
|
||||
);
|
||||
}
|
||||
|
||||
protected function createUserTalkPage( User $user ) {
|
||||
global $wgAutoWelcomeNewUsers;
|
||||
|
||||
if ( $wgAutoWelcomeNewUsers ) {
|
||||
$msg = "confirmaccount-welc-pos{$this->type}";
|
||||
$welcome = wfEmptyMsg( $msg )
|
||||
? wfMessage( 'confirmaccount-welc' )->text()
|
||||
: wfMessage( $msg )->text(); // custom message
|
||||
# Add user welcome message!
|
||||
$article = new WikiPage( $user->getTalkPage() );
|
||||
$article->doEdit(
|
||||
"{$welcome} ~~~~",
|
||||
wfMessage( 'confirmaccount-wsum' )->inContentLanguage()->text(),
|
||||
EDIT_MINOR,
|
||||
false,
|
||||
$this->admin
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
297
ConfirmAccount/business/AccountRequestSubmission.php
Normal file
297
ConfirmAccount/business/AccountRequestSubmission.php
Normal file
|
@ -0,0 +1,297 @@
|
|||
<?php
|
||||
|
||||
class AccountRequestSubmission {
|
||||
/* User making the request */
|
||||
protected $requester;
|
||||
/* Desired name and fields filled from form */
|
||||
protected $userName;
|
||||
protected $realName;
|
||||
protected $tosAccepted;
|
||||
protected $email;
|
||||
protected $bio;
|
||||
protected $notes;
|
||||
protected $urls;
|
||||
protected $type;
|
||||
/** @var array */
|
||||
protected $areas;
|
||||
protected $registration;
|
||||
protected $ip;
|
||||
protected $xff;
|
||||
protected $agent;
|
||||
/* File attachment fields */
|
||||
protected $attachmentSrcName; // user given attachment base name
|
||||
protected $attachmentPrevName; // user given attachment base name last attempt
|
||||
protected $attachmentDidNotForget; // user already saw "please re-attach" notice
|
||||
protected $attachmentSize; // bytes size of file
|
||||
protected $attachmentTempPath; // tmp path file was uploaded to FS
|
||||
|
||||
public function __construct( User $requester, array $params ) {
|
||||
$this->requester = $requester;
|
||||
$this->userName = trim( $params['userName'] );
|
||||
$this->realName = trim( $params['realName'] );
|
||||
$this->tosAccepted = $params['tosAccepted'];
|
||||
$this->email = $params['email'];
|
||||
$this->bio = trim( $params['bio'] );
|
||||
$this->notes = trim( $params['notes'] );
|
||||
$this->urls = trim( $params['urls'] );
|
||||
$this->type = $params['type'];
|
||||
$this->areas = $params['areas'];
|
||||
$this->ip = $params['ip'];
|
||||
$this->xff = $params['xff'];
|
||||
$this->agent = $params['agent'];
|
||||
$this->registration = wfTimestamp( TS_MW, $params['registration'] );
|
||||
$this->attachmentPrevName = $params['attachmentPrevName'];
|
||||
$this->attachmentSrcName = $params['attachmentSrcName'];
|
||||
$this->attachmentDidNotForget = $params['attachmentDidNotForget'];
|
||||
$this->attachmentSize = $params['attachmentSize'];
|
||||
$this->attachmentTempPath = $params['attachmentTempPath'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAttachmentDidNotForget() {
|
||||
return $this->attachmentDidNotForget;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getAttachtmentPrevName() {
|
||||
return $this->attachmentPrevName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to validate and submit this data to the DB
|
||||
* @param $context IContextSource
|
||||
* @return array( true or error key string, html error msg or null )
|
||||
*/
|
||||
public function submit( IContextSource $context ) {
|
||||
global $wgAuth, $wgAccountRequestThrottle, $wgMemc, $wgContLang;
|
||||
global $wgConfirmAccountRequestFormItems;
|
||||
|
||||
$formConfig = $wgConfirmAccountRequestFormItems; // convience
|
||||
$reqUser = $this->requester;
|
||||
|
||||
# Make sure that basic permissions are checked
|
||||
$block = ConfirmAccount::getAccountRequestBlock( $reqUser );
|
||||
if ( $block ) {
|
||||
return array(
|
||||
'accountreq_permission_denied',
|
||||
$context->msg( 'badaccess-group0' )->escaped()
|
||||
);
|
||||
} elseif ( wfReadOnly() ) {
|
||||
return array( 'accountreq_readonly', $context->msg( 'badaccess-group0' )->escaped() );
|
||||
}
|
||||
|
||||
# Now create a dummy user ($u) and check if it is valid
|
||||
if ( $this->userName === '' ) {
|
||||
return array( 'accountreq_no_name', $context->msg( 'noname' )->escaped() );
|
||||
}
|
||||
|
||||
//before we continue, verify user
|
||||
$code = sha1($_SERVER['REMOTE_ADDR'] . date('m'));
|
||||
$data = file_get_contents('http://scratch.mit.edu/site-api/comments/project/10135908/?page=1&salt=' . md5(time())); //add the salt so it doesn't cache
|
||||
if (!$data) {
|
||||
return array('api_failed', 'Accessing the API to verify your registration failed. Please try again later.');
|
||||
return;
|
||||
}
|
||||
$success = false;
|
||||
preg_match_all('%<div id="comments-\d+" class="comment.*?" data-comment-id="\d+">.*?<a href="/users/(.*?)">.*?<div class="content">(.*?)</div>%ms', $data, $matches);
|
||||
foreach ($matches[2] as $key => $val) {
|
||||
$user = $matches[1][$key];
|
||||
$comment = trim($val);
|
||||
if ($user == $this->userName && $comment == $code) {
|
||||
$success = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$success) {
|
||||
return array('no_comment', 'It does not appear you commented the verification code on the specified project. Please try again.');
|
||||
}
|
||||
|
||||
$u = User::newFromName( $this->userName, 'creatable' );
|
||||
if ( !$u ) {
|
||||
return array( 'accountreq_invalid_name', $context->msg( 'noname' )->escaped() );
|
||||
}
|
||||
# No request spamming...
|
||||
if ( $wgAccountRequestThrottle && $reqUser->isPingLimitable() ) {
|
||||
$key = wfMemcKey( 'acctrequest', 'ip', $this->ip );
|
||||
$value = (int)$wgMemc->get( $key );
|
||||
if ( $value > $wgAccountRequestThrottle ) {
|
||||
return array(
|
||||
'accountreq_throttled',
|
||||
$context->msg( 'acct_request_throttle_hit', $wgAccountRequestThrottle )->text()
|
||||
);
|
||||
}
|
||||
}
|
||||
# Make sure user agrees to policy here
|
||||
if ( $formConfig['TermsOfService']['enabled'] && !$this->tosAccepted ) {
|
||||
return array(
|
||||
'acct_request_skipped_tos',
|
||||
$context->msg( 'requestaccount-agree' )->escaped()
|
||||
);
|
||||
}
|
||||
# Validate email address
|
||||
/*if ( !Sanitizer::validateEmail( $this->email ) ) {
|
||||
return array(
|
||||
'acct_request_invalid_email',
|
||||
$context->msg( 'invalidemailaddress' )->escaped()
|
||||
);
|
||||
}*/
|
||||
# Check if biography is long enough
|
||||
/*if ( $formConfig['Biography']['enabled']
|
||||
&& str_word_count( $this->bio ) < $formConfig['Biography']['minWords'] )
|
||||
{
|
||||
$minWords = $formConfig['Biography']['minWords'];
|
||||
|
||||
return array(
|
||||
'acct_request_short_bio',
|
||||
$context->msg( 'requestaccount-tooshort' )->numParams( $minWords )->text()
|
||||
);
|
||||
}*/
|
||||
# Per security reasons, file dir cannot be pulled from client,
|
||||
# so ask them to resubmit it then...
|
||||
# If the extra fields are off, then uploads are off
|
||||
$allowFiles = $formConfig['CV']['enabled'];
|
||||
if ( $allowFiles && $this->attachmentPrevName && !$this->attachmentSrcName ) {
|
||||
# If the user is submitting forgotAttachment as true with no file,
|
||||
# then they saw the notice and choose not to re-select the file.
|
||||
# Assume that they don't want to send one anymore.
|
||||
if ( !$this->attachmentDidNotForget ) {
|
||||
$this->attachmentPrevName = '';
|
||||
$this->attachmentDidNotForget = 0;
|
||||
return array( false, $context->msg( 'requestaccount-resub' )->escaped() );
|
||||
}
|
||||
}
|
||||
# Check if already in use
|
||||
if ( 0 != $u->idForName() || $wgAuth->userExists( $u->getName() ) ) {
|
||||
return array(
|
||||
'accountreq_username_exists',
|
||||
$context->msg( 'userexists' )->escaped()
|
||||
);
|
||||
}
|
||||
# Set email and real name
|
||||
//$u->setEmail( $this->email );
|
||||
//$u->setRealName( $this->realName );
|
||||
|
||||
$dbw = wfGetDB( DB_MASTER );
|
||||
$dbw->begin(); // ready to acquire locks
|
||||
# Check pending accounts for name use
|
||||
if ( !UserAccountRequest::acquireUsername( $u->getName() ) ) {
|
||||
$dbw->rollback();
|
||||
return array(
|
||||
'accountreq_username_pending',
|
||||
$context->msg( 'requestaccount-inuse' )->escaped()
|
||||
);
|
||||
}
|
||||
# Check if someone else has an account request with the same email
|
||||
/*if ( !UserAccountRequest::acquireEmail( $u->getEmail() ) ) {
|
||||
$dbw->rollback();
|
||||
return array(
|
||||
'acct_request_email_exists',
|
||||
$context->msg( 'requestaccount-emaildup' )->escaped()
|
||||
);
|
||||
}*/
|
||||
# Process upload...
|
||||
if ( $allowFiles && $this->attachmentSrcName ) {
|
||||
global $wgAccountRequestExts, $wgConfirmAccountFSRepos;
|
||||
|
||||
$ext = explode( '.', $this->attachmentSrcName );
|
||||
$finalExt = $ext[count( $ext ) - 1];
|
||||
# File must have size.
|
||||
if ( trim( $this->attachmentSrcName ) == '' || empty( $this->attachmentSize ) ) {
|
||||
$this->attachmentPrevName = '';
|
||||
$dbw->rollback();
|
||||
return array( 'acct_request_empty_file', $context->msg( 'emptyfile' )->escaped() );
|
||||
}
|
||||
# Look at the contents of the file; if we can recognize the
|
||||
# type but it's corrupt or data of the wrong type, we should
|
||||
# probably not accept it.
|
||||
if ( !in_array( $finalExt, $wgAccountRequestExts ) ) {
|
||||
$this->attachmentPrevName = '';
|
||||
$dbw->rollback();
|
||||
return array(
|
||||
'acct_request_bad_file_ext',
|
||||
$context->msg( 'requestaccount-exts' )->escaped()
|
||||
);
|
||||
}
|
||||
$veri = ConfirmAccount::verifyAttachment( $this->attachmentTempPath, $finalExt );
|
||||
if ( !$veri->isGood() ) {
|
||||
$this->attachmentPrevName = '';
|
||||
$dbw->rollback();
|
||||
return array(
|
||||
'acct_request_corrupt_file',
|
||||
$context->msg( 'verification-error' )->escaped()
|
||||
);
|
||||
}
|
||||
# Start a transaction, move file from temp to account request directory.
|
||||
$repo = new FSRepo( $wgConfirmAccountFSRepos['accountreqs'] );
|
||||
$key = sha1_file( $this->attachmentTempPath ) . '.' . $finalExt;
|
||||
$pathRel = UserAccountRequest::relPathFromKey( $key );
|
||||
$triplet = array( $this->attachmentTempPath, 'public', $pathRel );
|
||||
$status = $repo->storeBatch( array( $triplet ), FSRepo::OVERWRITE_SAME ); // save!
|
||||
if ( !$status->isOk() ) {
|
||||
$dbw->rollback();
|
||||
return array( 'acct_request_file_store_error',
|
||||
$context->msg( 'filecopyerror', $this->attachmentTempPath, $pathRel )->escaped() );
|
||||
}
|
||||
}
|
||||
$expires = null; // passed by reference
|
||||
$token = ConfirmAccount::getConfirmationToken( $u, $expires );
|
||||
|
||||
# Insert into pending requests...
|
||||
$req = UserAccountRequest::newFromArray( array(
|
||||
'name' => $u->getName(),
|
||||
'email' => rand(1,10000000) . '@' . rand(1, 10000000) . '.com',
|
||||
'real_name' => $u->getRealName(),
|
||||
'registration' => $this->registration,
|
||||
'bio' => $this->bio,
|
||||
'notes' => $this->notes,
|
||||
'urls' => $this->urls,
|
||||
'filename' => isset( $this->attachmentSrcName )
|
||||
? $this->attachmentSrcName
|
||||
: null,
|
||||
'type' => $this->type,
|
||||
'areas' => $this->areas,
|
||||
'storage_key' => isset( $key ) ? $key : null,
|
||||
'comment' => '',
|
||||
'email_token' => md5( $token ),
|
||||
'email_token_expires' => $expires,
|
||||
'ip' => $this->ip,
|
||||
'xff' => $this->xff,
|
||||
'agent' => $this->agent
|
||||
) );
|
||||
$req->insertOn();
|
||||
# Send confirmation, required!
|
||||
/*$result = ConfirmAccount::sendConfirmationMail( $u, $this->ip, $token, $expires );
|
||||
if ( !$result->isOK() ) {
|
||||
$dbw->rollback(); // nevermind
|
||||
if ( isset( $repo ) && isset( $pathRel ) ) { // remove attachment
|
||||
$repo->cleanupBatch( array( array( 'public', $pathRel ) ) );
|
||||
}
|
||||
|
||||
$param = $context->getOutput()->parse( $result->getWikiText() );
|
||||
|
||||
return array(
|
||||
'acct_request_mail_failed',
|
||||
$context->msg( 'mailerror' )->rawParams( $param )->escaped() );
|
||||
}
|
||||
$dbw->commit();*/
|
||||
|
||||
# Clear cache for notice of how many account requests there are
|
||||
ConfirmAccount::clearAccountRequestCountCache();
|
||||
# No request spamming...
|
||||
if ( $wgAccountRequestThrottle && $reqUser->isPingLimitable() ) {
|
||||
$ip = $context->getRequest()->getIP();
|
||||
$key = wfMemcKey( 'acctrequest', 'ip', $ip );
|
||||
$value = $wgMemc->incr( $key );
|
||||
if ( !$value ) {
|
||||
$wgMemc->set( $key, 1, 86400 );
|
||||
}
|
||||
}
|
||||
# Done!
|
||||
return array( true, null );
|
||||
}
|
||||
}
|
99
ConfirmAccount/frontend/ConfirmAccountUI.hooks.php
Normal file
99
ConfirmAccount/frontend/ConfirmAccountUI.hooks.php
Normal file
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
/**
|
||||
* Class containing hooked functions for a ConfirmAccount environment
|
||||
*/
|
||||
class ConfirmAccountUIHooks {
|
||||
/**
|
||||
* @param $template
|
||||
* @return bool
|
||||
*/
|
||||
public static function addRequestLoginText( &$template ) {
|
||||
$context = RequestContext::getMain();
|
||||
# Add a link to RequestAccount from UserLogin
|
||||
if ( !$context->getUser()->isAllowed( 'createaccount' ) ) {
|
||||
$template->set( 'header', $context->msg( 'requestaccount-loginnotice' )->parseAsBlock() );
|
||||
|
||||
$context->getOutput()->addModules( 'ext.confirmAccount' ); // CSS
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $personal_urls
|
||||
* @param $title
|
||||
* @return bool
|
||||
*/
|
||||
public static function setRequestLoginLinks( array &$personal_urls, &$title ) {
|
||||
if ( isset( $personal_urls['anonlogin'] ) ) {
|
||||
$personal_urls['anonlogin']['text'] = wfMessage( 'nav-login-createaccount' )->escaped();
|
||||
} elseif ( isset( $personal_urls['login'] ) ) {
|
||||
$personal_urls['login']['text'] = wfMessage( 'nav-login-createaccount' )->escaped();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $user User
|
||||
* @param $abortError
|
||||
* @return bool
|
||||
*/
|
||||
public static function checkIfAccountNameIsPending( User $user, &$abortError ) {
|
||||
# If an account is made with name X, and one is pending with name X
|
||||
# we will have problems if the pending one is later confirmed
|
||||
if ( !UserAccountRequest::acquireUsername( $user->getName() ) ) {
|
||||
$abortError = wfMessage( 'requestaccount-inuse' )->escaped();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add "x email-confirmed open account requests" notice
|
||||
* @param $notice
|
||||
* @return bool
|
||||
*/
|
||||
public static function confirmAccountsNotice( OutputPage &$out, Skin &$skin ) {
|
||||
global $wgConfirmAccountNotice;
|
||||
|
||||
$context = $out->getContext();
|
||||
if ( !$wgConfirmAccountNotice || !$context->getUser()->isAllowed( 'confirmaccount' ) ) {
|
||||
return true;
|
||||
}
|
||||
# Only show on some special pages
|
||||
$title = $context->getTitle();
|
||||
if ( !$title->isSpecial( 'Recentchanges' ) && !$title->isSpecial( 'Watchlist' ) ) {
|
||||
return true;
|
||||
}
|
||||
$count = ConfirmAccount::getOpenEmailConfirmedCount( '*' );
|
||||
if ( $count > 0 ) {
|
||||
$out->prependHtml(
|
||||
'<div id="mw-confirmaccount-msg" class="plainlinks mw-confirmaccount-bar">' .
|
||||
$context->msg( 'confirmaccount-newrequests' )->numParams( $count )->parse() .
|
||||
'</div>'
|
||||
);
|
||||
|
||||
$out->addModules( 'ext.confirmAccount' ); // CSS
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* For AdminLinks extension
|
||||
* @param $admin_links_tree
|
||||
* @return bool
|
||||
*/
|
||||
public static function confirmAccountAdminLinks( &$admin_links_tree ) {
|
||||
$users_section = $admin_links_tree->getSection( wfMessage( 'adminlinks_users' )->escaped() );
|
||||
$extensions_row = $users_section->getRow( 'extensions' );
|
||||
|
||||
if ( is_null( $extensions_row ) ) {
|
||||
$extensions_row = new ALRow( 'extensions' );
|
||||
$users_section->addRow( $extensions_row );
|
||||
}
|
||||
|
||||
$extensions_row->addItem( ALItem::newFromSpecialPage( 'ConfirmAccounts' ) );
|
||||
$extensions_row->addItem( ALItem::newFromSpecialPage( 'UserCredentials' ) );
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
52
ConfirmAccount/frontend/ConfirmAccountUI.setup.php
Normal file
52
ConfirmAccount/frontend/ConfirmAccountUI.setup.php
Normal file
|
@ -0,0 +1,52 @@
|
|||
<?php
|
||||
/**
|
||||
* Class containing hooked functions for a ConfirmAccount environment
|
||||
*/
|
||||
class ConfirmAccountUISetup {
|
||||
/**
|
||||
* Register ConfirmAccount hooks.
|
||||
* @param $hooks Array $wgHooks (assoc array of hooks and handlers)
|
||||
* @return void
|
||||
*/
|
||||
public static function defineHookHandlers( array &$hooks ) {
|
||||
# Make sure "login / create account" notice still as "create account"
|
||||
$hooks['PersonalUrls'][] = 'ConfirmAccountUIHooks::setRequestLoginLinks';
|
||||
# Add notice of where to request an account at UserLogin
|
||||
$hooks['UserCreateForm'][] = 'ConfirmAccountUIHooks::addRequestLoginText';
|
||||
$hooks['UserLoginForm'][] = 'ConfirmAccountUIHooks::addRequestLoginText';
|
||||
# Status header like "new messages" bar
|
||||
$hooks['BeforePageDisplay'][] = 'ConfirmAccountUIHooks::confirmAccountsNotice';
|
||||
# Register admin pages for AdminLinks extension.
|
||||
$hooks['AdminLinks'][] = 'ConfirmAccountUIHooks::confirmAccountAdminLinks';
|
||||
}
|
||||
|
||||
/**
|
||||
* Register ConfirmAccount special pages as needed.
|
||||
* @param $pages Array $wgSpecialPages (list of special pages)
|
||||
* @param $groups Array $wgSpecialPageGroups (assoc array of special page groups)
|
||||
* @return void
|
||||
*/
|
||||
public static function defineSpecialPages( array &$pages, array &$groups ) {
|
||||
$pages['RequestAccount'] = 'RequestAccountPage';
|
||||
$groups['RequestAccount'] = 'login';
|
||||
|
||||
$pages['ConfirmAccounts'] = 'ConfirmAccountsPage';
|
||||
$groups['ConfirmAccounts'] = 'users';
|
||||
|
||||
$pages['UserCredentials'] = 'UserCredentialsPage';
|
||||
$groups['UserCredentials'] = 'users';
|
||||
}
|
||||
|
||||
/**
|
||||
* Append ConfirmAccount resource module definitions
|
||||
* @param $modules Array $wgResourceModules
|
||||
* @return void
|
||||
*/
|
||||
public static function defineResourceModules( array &$modules ) {
|
||||
$modules['ext.confirmAccount'] = array(
|
||||
'styles' => 'confirmaccount.css',
|
||||
'localBasePath' => dirname( __FILE__ ) . '/modules',
|
||||
'remoteExtPath' => 'ConfirmAccount/frontend/modules',
|
||||
);
|
||||
}
|
||||
}
|
400
ConfirmAccount/frontend/language/ConfirmAccount.alias.php
Normal file
400
ConfirmAccount/frontend/language/ConfirmAccount.alias.php
Normal file
|
@ -0,0 +1,400 @@
|
|||
<?php
|
||||
/**
|
||||
* Aliases for extension ConfirmAccount
|
||||
*
|
||||
* @file
|
||||
* @ingroup Extensions
|
||||
*/
|
||||
|
||||
$specialPageAliases = array();
|
||||
|
||||
/** English (English) */
|
||||
$specialPageAliases['en'] = array(
|
||||
'RequestAccount' => array( 'RequestAccount' ),
|
||||
'ConfirmAccounts' => array( 'ConfirmAccounts' ),
|
||||
'UserCredentials' => array( 'UserCredentials' ),
|
||||
);
|
||||
|
||||
/** Arabic (العربية) */
|
||||
$specialPageAliases['ar'] = array(
|
||||
'RequestAccount' => array( 'طلب_حساب' ),
|
||||
'ConfirmAccounts' => array( 'تأكيد_الحساب' ),
|
||||
'UserCredentials' => array( 'شهادات_المستخدم' ),
|
||||
);
|
||||
|
||||
/** Egyptian Spoken Arabic (مصرى) */
|
||||
$specialPageAliases['arz'] = array(
|
||||
'RequestAccount' => array( 'طلب_حساب' ),
|
||||
'ConfirmAccounts' => array( 'تأكيد_الحساب' ),
|
||||
'UserCredentials' => array( 'شهادات_اليوزر' ),
|
||||
);
|
||||
|
||||
/** Assamese (অসমীয়া) */
|
||||
$specialPageAliases['as'] = array(
|
||||
'RequestAccount' => array( 'একাউণ্ট_অনুৰোধ' ),
|
||||
'ConfirmAccounts' => array( 'একাউণ্ট_নিশ্চিত_কৰক' ),
|
||||
);
|
||||
|
||||
/** Bashkir (башҡортса) */
|
||||
$specialPageAliases['ba'] = array(
|
||||
'RequestAccount' => array( 'RequestAccount' ),
|
||||
);
|
||||
|
||||
/** Banjar (Bahasa Banjar) */
|
||||
$specialPageAliases['bjn'] = array(
|
||||
'RequestAccount' => array( 'Minta_akun' ),
|
||||
);
|
||||
|
||||
/** Breton (brezhoneg) */
|
||||
$specialPageAliases['br'] = array(
|
||||
'RequestAccount' => array( 'GoulennKont' ),
|
||||
'ConfirmAccounts' => array( 'KadarnaatKont' ),
|
||||
);
|
||||
|
||||
/** Bosnian (bosanski) */
|
||||
$specialPageAliases['bs'] = array(
|
||||
'RequestAccount' => array( 'ZahtjevajRacun' ),
|
||||
'ConfirmAccounts' => array( 'PotvrdiRacun' ),
|
||||
'UserCredentials' => array( 'KorisnickePotvrde' ),
|
||||
);
|
||||
|
||||
/** German (Deutsch) */
|
||||
$specialPageAliases['de'] = array(
|
||||
'RequestAccount' => array( 'Benutzerkonto_beantragen' ),
|
||||
'ConfirmAccounts' => array( 'Benutzerkonto_bestätigen' ),
|
||||
'UserCredentials' => array( 'Benutzerangaben' ),
|
||||
);
|
||||
|
||||
/** Zazaki (Zazaki) */
|
||||
$specialPageAliases['diq'] = array(
|
||||
'RequestAccount' => array( 'HesabWaştış' ),
|
||||
'ConfirmAccounts' => array( 'HesabRaştkerdış' ),
|
||||
'UserCredentials' => array( 'ReferansêKarberan' ),
|
||||
);
|
||||
|
||||
/** Lower Sorbian (dolnoserbski) */
|
||||
$specialPageAliases['dsb'] = array(
|
||||
'RequestAccount' => array( 'Póžedanje_na_konto' ),
|
||||
'ConfirmAccounts' => array( 'Konto_wobkšuśiś' ),
|
||||
'UserCredentials' => array( 'Wužywarske_pódaśa' ),
|
||||
);
|
||||
|
||||
/** Greek (Ελληνικά) */
|
||||
$specialPageAliases['el'] = array(
|
||||
'RequestAccount' => array( 'ΑίτησηΛογαριασμού' ),
|
||||
'ConfirmAccounts' => array( 'ΕπιβεβαίωσηΛογαριασμού' ),
|
||||
'UserCredentials' => array( 'ΣυστάσειςΧρήστη' ),
|
||||
);
|
||||
|
||||
/** Esperanto (Esperanto) */
|
||||
$specialPageAliases['eo'] = array(
|
||||
'RequestAccount' => array( 'Peti_konton' ),
|
||||
'ConfirmAccounts' => array( 'Konfirmi_konton' ),
|
||||
'UserCredentials' => array( 'Datumoj_pri_uzantoj' ),
|
||||
);
|
||||
|
||||
/** Spanish (español) */
|
||||
$specialPageAliases['es'] = array(
|
||||
'RequestAccount' => array( 'Pedir_cuenta_de_usuario', 'PedirCuentaUsuario' ),
|
||||
'ConfirmAccounts' => array( 'Confirmar_cuentas' ),
|
||||
'UserCredentials' => array( 'Credenciales' ),
|
||||
);
|
||||
|
||||
/** Persian (فارسی) */
|
||||
$specialPageAliases['fa'] = array(
|
||||
'RequestAccount' => array( 'درخواست_حساب' ),
|
||||
'ConfirmAccounts' => array( 'تایید_حسابها' ),
|
||||
'UserCredentials' => array( 'شناسه_کاربری' ),
|
||||
);
|
||||
|
||||
/** Finnish (suomi) */
|
||||
$specialPageAliases['fi'] = array(
|
||||
'RequestAccount' => array( 'Pyydä_käyttäjätunnusta' ),
|
||||
'ConfirmAccounts' => array( 'Varmista_käyttäjätunnus' ),
|
||||
);
|
||||
|
||||
/** French (français) */
|
||||
$specialPageAliases['fr'] = array(
|
||||
'RequestAccount' => array( 'Demander_un_compte', 'DemanderUnCompte' ),
|
||||
'ConfirmAccounts' => array( 'ConfirmerCompte', 'Confirmation_compte', 'ConfirmationCompte' ),
|
||||
);
|
||||
|
||||
/** Franco-Provençal (arpetan) */
|
||||
$specialPageAliases['frp'] = array(
|
||||
'RequestAccount' => array( 'Demandar_un_compto', 'DemandarUnCompto' ),
|
||||
'ConfirmAccounts' => array( 'Confirmar_lo_compto', 'ConfirmarLoCompto', 'Confirmacion_de_compto', 'ConfirmacionDeCompto' ),
|
||||
'UserCredentials' => array( 'Refèrences_a_l\'usanciér', 'RefèrencesALUsanciér' ),
|
||||
);
|
||||
|
||||
/** Galician (galego) */
|
||||
$specialPageAliases['gl'] = array(
|
||||
'RequestAccount' => array( 'Solicitar_unha_conta' ),
|
||||
'ConfirmAccounts' => array( 'Confirmar_a_conta' ),
|
||||
'UserCredentials' => array( 'Credenciais_de_usuario' ),
|
||||
);
|
||||
|
||||
/** Swiss German (Alemannisch) */
|
||||
$specialPageAliases['gsw'] = array(
|
||||
'RequestAccount' => array( 'Aatrag_stelle_fir_e_Benutzerchonto' ),
|
||||
'ConfirmAccounts' => array( 'Benutzerchonto_bstetige' ),
|
||||
);
|
||||
|
||||
/** Hebrew (עברית) */
|
||||
$specialPageAliases['he'] = array(
|
||||
'RequestAccount' => array( 'בקשת_חשבון' ),
|
||||
'ConfirmAccounts' => array( 'אישור_חשבונות' ),
|
||||
'UserCredentials' => array( 'פרטי_משתמש' ),
|
||||
);
|
||||
|
||||
/** Croatian (hrvatski) */
|
||||
$specialPageAliases['hr'] = array(
|
||||
'RequestAccount' => array( 'Zatraži_račun' ),
|
||||
'ConfirmAccounts' => array( 'Potvrdi_račun' ),
|
||||
'UserCredentials' => array( 'Suradničke_vjerodajnice' ),
|
||||
);
|
||||
|
||||
/** Upper Sorbian (hornjoserbsce) */
|
||||
$specialPageAliases['hsb'] = array(
|
||||
'RequestAccount' => array( 'Konto_požadać' ),
|
||||
'ConfirmAccounts' => array( 'Konto_potwjerdźić' ),
|
||||
'UserCredentials' => array( 'Wužywarske_podaća' ),
|
||||
);
|
||||
|
||||
/** Haitian (Kreyòl ayisyen) */
|
||||
$specialPageAliases['ht'] = array(
|
||||
'RequestAccount' => array( 'MandKont' ),
|
||||
'ConfirmAccounts' => array( 'KonfimeKont' ),
|
||||
'UserCredentials' => array( 'DwaItilizatèYo' ),
|
||||
);
|
||||
|
||||
/** Hungarian (magyar) */
|
||||
$specialPageAliases['hu'] = array(
|
||||
'RequestAccount' => array( 'Felhasználói_fiók_igénylése' ),
|
||||
'ConfirmAccounts' => array( 'Felhasználói_fiók_megerősítése' ),
|
||||
'UserCredentials' => array( 'Felhasználói_ajánlólevél' ),
|
||||
);
|
||||
|
||||
/** Interlingua (interlingua) */
|
||||
$specialPageAliases['ia'] = array(
|
||||
'RequestAccount' => array( 'Requestar_conto' ),
|
||||
'ConfirmAccounts' => array( 'Confirmar_contos' ),
|
||||
'UserCredentials' => array( 'Referentias_del_usator' ),
|
||||
);
|
||||
|
||||
/** Indonesian (Bahasa Indonesia) */
|
||||
$specialPageAliases['id'] = array(
|
||||
'RequestAccount' => array( 'Minta_akun', 'MintaAkun' ),
|
||||
'ConfirmAccounts' => array( 'Konfirmasi_akun', 'KonfirmasiAkun' ),
|
||||
'UserCredentials' => array( 'Kredensial_pengguna', 'KredensialPengguna' ),
|
||||
);
|
||||
|
||||
/** Italian (italiano) */
|
||||
$specialPageAliases['it'] = array(
|
||||
'UserCredentials' => array( 'CredenzialiUtente' ),
|
||||
);
|
||||
|
||||
/** Japanese (日本語) */
|
||||
$specialPageAliases['ja'] = array(
|
||||
'RequestAccount' => array( 'アカウント申請', 'アカウント登録申請' ),
|
||||
'ConfirmAccounts' => array( 'アカウント承認', 'アカウントの承認', 'アカウント申請の承認', 'アカウント登録申請の承認' ),
|
||||
'UserCredentials' => array( '利用者信頼情報' ),
|
||||
);
|
||||
|
||||
/** Georgian (ქართული) */
|
||||
$specialPageAliases['ka'] = array(
|
||||
'ConfirmAccounts' => array( 'ანგარიშის_დადასტურება' ),
|
||||
);
|
||||
|
||||
/** Khmer (ភាសាខ្មែរ) */
|
||||
$specialPageAliases['km'] = array(
|
||||
'RequestAccount' => array( 'ស្នើសុំគណនី' ),
|
||||
'ConfirmAccounts' => array( 'បញ្ជាក់ទទួលស្គាល់គណនី' ),
|
||||
);
|
||||
|
||||
/** Korean (한국어) */
|
||||
$specialPageAliases['ko'] = array(
|
||||
'RequestAccount' => array( '계정요청' ),
|
||||
'ConfirmAccounts' => array( '계정인증', '계정승인' ),
|
||||
'UserCredentials' => array( '계정자격증명' ),
|
||||
);
|
||||
|
||||
/** Colognian (Ripoarisch) */
|
||||
$specialPageAliases['ksh'] = array(
|
||||
'RequestAccount' => array( 'Metmaacherzohjang_beaandraare' ),
|
||||
'ConfirmAccounts' => array( 'Metmaacherzohjang_beshtätejje' ),
|
||||
'UserCredentials' => array( 'Metmaache-Aanjabe' ),
|
||||
);
|
||||
|
||||
/** Ladino (Ladino) */
|
||||
$specialPageAliases['lad'] = array(
|
||||
'RequestAccount' => array( 'Demandar_cuento_de_usador' ),
|
||||
'ConfirmAccounts' => array( 'AverdadearCuentos' ),
|
||||
'UserCredentials' => array( 'Letra_de_creença_de_usadores' ),
|
||||
);
|
||||
|
||||
/** Luxembourgish (Lëtzebuergesch) */
|
||||
$specialPageAliases['lb'] = array(
|
||||
'RequestAccount' => array( 'Benotzerkont_ufroen' ),
|
||||
'ConfirmAccounts' => array( 'Benotzerkont_confirméieren' ),
|
||||
'UserCredentials' => array( 'Benotzerinformatiounen' ),
|
||||
);
|
||||
|
||||
/** Macedonian (македонски) */
|
||||
$specialPageAliases['mk'] = array(
|
||||
'RequestAccount' => array( 'ПобарајКорисничкаСметка' ),
|
||||
'ConfirmAccounts' => array( 'ПотврдаНаКорисничкаСметка' ),
|
||||
'UserCredentials' => array( 'КорисничкиАкдредитиви' ),
|
||||
);
|
||||
|
||||
/** Malayalam (മലയാളം) */
|
||||
$specialPageAliases['ml'] = array(
|
||||
'RequestAccount' => array( 'അംഗത്വം_ആവശ്യപ്പെടുക' ),
|
||||
'ConfirmAccounts' => array( 'അംഗത്വം_സ്ഥിരീകരിക്കുക' ),
|
||||
'UserCredentials' => array( 'ഉപയോക്തൃയോഗ്യത' ),
|
||||
);
|
||||
|
||||
/** Marathi (मराठी) */
|
||||
$specialPageAliases['mr'] = array(
|
||||
'RequestAccount' => array( 'खातेविनंती' ),
|
||||
'ConfirmAccounts' => array( 'खातेनिश्चिती' ),
|
||||
'UserCredentials' => array( 'सदस्यपरिचयप्त्र' ),
|
||||
);
|
||||
|
||||
/** Malay (Bahasa Melayu) */
|
||||
$specialPageAliases['ms'] = array(
|
||||
'ConfirmAccounts' => array( 'Sahkan_akaun', 'Mengesahkan_akaun' ),
|
||||
);
|
||||
|
||||
/** Maltese (Malti) */
|
||||
$specialPageAliases['mt'] = array(
|
||||
'RequestAccount' => array( 'RikjestaKont' ),
|
||||
'ConfirmAccounts' => array( 'KonfermaKont' ),
|
||||
'UserCredentials' => array( 'KredenzjaliUtent' ),
|
||||
);
|
||||
|
||||
/** Norwegian Bokmål (norsk (bokmål)) */
|
||||
$specialPageAliases['nb'] = array(
|
||||
'RequestAccount' => array( 'Etterspør_konto' ),
|
||||
'ConfirmAccounts' => array( 'Bekreft_konto' ),
|
||||
'UserCredentials' => array( 'Brukerlegitimasjon' ),
|
||||
);
|
||||
|
||||
/** Nedersaksisch (Nedersaksisch) */
|
||||
$specialPageAliases['nds-nl'] = array(
|
||||
'RequestAccount' => array( 'Gebruker_anvragen' ),
|
||||
'ConfirmAccounts' => array( 'Gebruker_bevestigen' ),
|
||||
'UserCredentials' => array( 'Gebrukersgetuugschrift' ),
|
||||
);
|
||||
|
||||
/** Dutch (Nederlands) */
|
||||
$specialPageAliases['nl'] = array(
|
||||
'RequestAccount' => array( 'GebruikerAanvragen' ),
|
||||
'ConfirmAccounts' => array( 'GebruikerBevestigen' ),
|
||||
'UserCredentials' => array( 'Gebruikersattest' ),
|
||||
);
|
||||
|
||||
/** Occitan (occitan) */
|
||||
$specialPageAliases['oc'] = array(
|
||||
'RequestAccount' => array( 'DemandarUnCompte', 'Demandar_un_compte' ),
|
||||
'ConfirmAccounts' => array( 'ConfirmarCompte', 'Confirmacion_compte', 'ConfirmacionCompte' ),
|
||||
);
|
||||
|
||||
/** Polish (polski) */
|
||||
$specialPageAliases['pl'] = array(
|
||||
'RequestAccount' => array( 'Prośba_o_utworzenie_konta' ),
|
||||
'ConfirmAccounts' => array( 'Potwierdzenie_konta' ),
|
||||
);
|
||||
|
||||
/** Portuguese (português) */
|
||||
$specialPageAliases['pt'] = array(
|
||||
'RequestAccount' => array( 'Pedir_conta' ),
|
||||
'ConfirmAccounts' => array( 'Confirmar_contas' ),
|
||||
'UserCredentials' => array( 'Credenciais_de_utilizador' ),
|
||||
);
|
||||
|
||||
/** Brazilian Portuguese (português do Brasil) */
|
||||
$specialPageAliases['pt-br'] = array(
|
||||
'ConfirmAccounts' => array( 'Confirmar_conta' ),
|
||||
'UserCredentials' => array( 'Credenciais_de_usuário' ),
|
||||
);
|
||||
|
||||
/** Romanian (română) */
|
||||
$specialPageAliases['ro'] = array(
|
||||
'RequestAccount' => array( 'Cerere_cont' ),
|
||||
'ConfirmAccounts' => array( 'Confirmă_conturi' ),
|
||||
'UserCredentials' => array( 'Detalii_utilizator' ),
|
||||
);
|
||||
|
||||
/** Russian (русский) */
|
||||
$specialPageAliases['ru'] = array(
|
||||
'RequestAccount' => array( 'Запросить_учётную_запись' ),
|
||||
);
|
||||
|
||||
/** Sanskrit (संस्कृतम्) */
|
||||
$specialPageAliases['sa'] = array(
|
||||
'RequestAccount' => array( 'उपयोजकसंज्ञाविनन्ती' ),
|
||||
'ConfirmAccounts' => array( 'उपयोजकसंज्ञापुष्टिकरोति' ),
|
||||
'UserCredentials' => array( 'उपयोजकविश्वासपत्त्र' ),
|
||||
);
|
||||
|
||||
/** Slovak (slovenčina) */
|
||||
$specialPageAliases['sk'] = array(
|
||||
'RequestAccount' => array( 'PožiadaťOÚčet' ),
|
||||
'ConfirmAccounts' => array( 'PotvrdiťÚčty' ),
|
||||
'UserCredentials' => array( 'PrihlasovacieÚdaje' ),
|
||||
);
|
||||
|
||||
/** Albanian (shqip) */
|
||||
$specialPageAliases['sq'] = array(
|
||||
'RequestAccount' => array( 'KërkoLlogari' ),
|
||||
'ConfirmAccounts' => array( 'KonfirmoLlogaritë' ),
|
||||
);
|
||||
|
||||
/** Swedish (svenska) */
|
||||
$specialPageAliases['sv'] = array(
|
||||
'ConfirmAccounts' => array( 'Bekräfta_konto' ),
|
||||
'UserCredentials' => array( 'Användarnamn_och_lösenord' ),
|
||||
);
|
||||
|
||||
/** Swahili (Kiswahili) */
|
||||
$specialPageAliases['sw'] = array(
|
||||
'RequestAccount' => array( 'OmbaAkaunti' ),
|
||||
'ConfirmAccounts' => array( 'ThibitishaAkaunti' ),
|
||||
);
|
||||
|
||||
/** Thai (ไทย) */
|
||||
$specialPageAliases['th'] = array(
|
||||
'ConfirmAccounts' => array( 'ยืนยันบัญชีผู้ใช้' ),
|
||||
);
|
||||
|
||||
/** Tagalog (Tagalog) */
|
||||
$specialPageAliases['tl'] = array(
|
||||
'RequestAccount' => array( 'Hilingin_ang_kuwenta', 'HilingKuwenta' ),
|
||||
'ConfirmAccounts' => array( 'Tiyakin_ang_mga_kuwenta' ),
|
||||
'UserCredentials' => array( 'Mga_katibayan_ng_katangian_ng_tagagamit' ),
|
||||
);
|
||||
|
||||
/** Turkish (Türkçe) */
|
||||
$specialPageAliases['tr'] = array(
|
||||
'RequestAccount' => array( 'Hesapİste' ),
|
||||
'ConfirmAccounts' => array( 'HesaplarıDoğrula' ),
|
||||
'UserCredentials' => array( 'KullanıcıReferansları' ),
|
||||
);
|
||||
|
||||
/** Ukrainian (українська) */
|
||||
$specialPageAliases['uk'] = array(
|
||||
'RequestAccount' => array( 'Запит_облікового_запису' ),
|
||||
);
|
||||
|
||||
/** Simplified Chinese (中文(简体)) */
|
||||
$specialPageAliases['zh-hans'] = array(
|
||||
'RequestAccount' => array( '申请帐户' ),
|
||||
'ConfirmAccounts' => array( '确认帐户' ),
|
||||
'UserCredentials' => array( '用户凭据' ),
|
||||
);
|
||||
|
||||
/** Traditional Chinese (中文(繁體)) */
|
||||
$specialPageAliases['zh-hant'] = array(
|
||||
'RequestAccount' => array( '請求帳戶' ),
|
||||
'ConfirmAccounts' => array( '確認帳戶' ),
|
||||
);
|
830
ConfirmAccount/frontend/language/ConfirmAccount.i18n.php
Normal file
830
ConfirmAccount/frontend/language/ConfirmAccount.i18n.php
Normal file
|
@ -0,0 +1,830 @@
|
|||
<?php
|
||||
/**
|
||||
* Internationalisation file for ConfirmAccount extension.
|
||||
*
|
||||
* @file
|
||||
* @ingroup Extensions
|
||||
*/
|
||||
|
||||
$messages = array();
|
||||
|
||||
$messages['en'] = array(
|
||||
# Site message for admins
|
||||
'confirmaccount-newrequests' => '\'\'\'$1\'\'\' open e-mail confirmed [[Special:ConfirmAccounts|account {{PLURAL:$1|request is pending|requests are pending}}]]. \'\'\'Your attention is needed!\'\'\'',
|
||||
|
||||
# Add to Special:Login
|
||||
'requestaccount-loginnotice' => 'To obtain a user account, you must \'\'\'[[Special:RequestAccount|request one]]\'\'\'.',
|
||||
|
||||
# User rights descriptions
|
||||
'right-confirmaccount' => 'View the [[Special:ConfirmAccounts|queue with requested accounts]]',
|
||||
'right-requestips' => 'View requester\'s IP addresses while processing requested accounts',
|
||||
'right-lookupcredentials' => 'View [[Special:UserCredentials|user credentials]]',
|
||||
);
|
||||
|
||||
/** Message documentation (Message documentation)
|
||||
* @author Bennylin
|
||||
* @author EugeneZelenko
|
||||
* @author Jon Harald Søby
|
||||
* @author Lejonel
|
||||
* @author McDutchie
|
||||
* @author Purodha
|
||||
* @author Siebrand
|
||||
* @author The Evil IP address
|
||||
*/
|
||||
$messages['qqq'] = array(
|
||||
'confirmaccount-newrequests' => 'Notice for account reviewers when there are account requests from users with a confirmed e-mail address. Parameters:
|
||||
* $1 is the number of open account requests matching given criteria.',
|
||||
'right-confirmaccount' => '{{doc-right|confirmaccount}}',
|
||||
'right-requestips' => '{{doc-right|requestips}}',
|
||||
'right-lookupcredentials' => '{{doc-right|lookupcredentials}}',
|
||||
);
|
||||
|
||||
/** Arabic (العربية)
|
||||
* @author Ciphers
|
||||
* @author DRIHEM
|
||||
* @author Meno25
|
||||
* @author OsamaK
|
||||
* @author ترجمان05
|
||||
*/
|
||||
$messages['ar'] = array(
|
||||
'confirmaccount-newrequests' => "'''$1''' تم تأكيد البريد الإلكتروني المفتوح [[Special:ConfirmAccounts|هناك {{PLURAL:$1|حساب في الإنتظار|طلبات في الإنتظار}}]]. '''أنتباهك مطلوب!'''",
|
||||
'requestaccount-loginnotice' => "للحصول على حساب، يجب عليك '''[[Special:RequestAccount|أن تطلب حسابًا]]'''.",
|
||||
'right-confirmaccount' => 'عرض [[Special:ConfirmAccounts|طابور الحسابات المطلوبة]]',
|
||||
'right-requestips' => 'عرض عنوان آيبي الطالب أثناء العمل على الحسابات المطلوبة',
|
||||
'right-lookupcredentials' => 'رؤية [[Special:UserCredentials|شهادات المستخدم]]',
|
||||
);
|
||||
|
||||
/** Egyptian Spoken Arabic (مصرى)
|
||||
* @author Meno25
|
||||
*/
|
||||
$messages['arz'] = array(
|
||||
'confirmaccount-newrequests' => "{{PLURAL:$1|يوجد|يوجد}} حاليا '''$1'''
|
||||
{{PLURAL:$1|[[Special:ConfirmAccounts|طلب حساب]]|[[Special:ConfirmAccounts|طلب حساب]]}} مفتوح قيد الانتظار.", # Fuzzy
|
||||
'requestaccount-loginnotice' => "للحصول على حساب، يجب عليك '''[[Special:RequestAccount|طلب واحد]]'''.",
|
||||
);
|
||||
|
||||
/** Asturian (asturianu)
|
||||
* @author Xuacu
|
||||
*/
|
||||
$messages['ast'] = array(
|
||||
'confirmaccount-newrequests' => "Anguaño hai '''$1''' [[Special:ConfirmAccounts|{{PLURAL:$1|solicitú de cuenta pendiente|solicitúes de cuentes pendientes}}]]. '''Fai falta la to atención!'''",
|
||||
'requestaccount-loginnotice' => "Pa tener una cuenta d'usuariu, tienes de '''[[Special:RequestAccount|solicitar una]]'''.",
|
||||
'right-confirmaccount' => 'Ver la [[Special:ConfirmAccounts|cola de solicitúes de cuentes]]',
|
||||
'right-requestips' => 'Ver la direición IP del solicitante al procesar les solicitúes de cuentes',
|
||||
'right-lookupcredentials' => 'Ver les [[Special:UserCredentials|credenciales del usuariu]]',
|
||||
);
|
||||
|
||||
/** Belarusian (Taraškievica orthography) (беларуская (тарашкевіца))
|
||||
* @author EugeneZelenko
|
||||
* @author Jim-by
|
||||
* @author Renessaince
|
||||
* @author Zedlik
|
||||
*/
|
||||
$messages['be-tarask'] = array(
|
||||
'confirmaccount-newrequests' => "Чакаецца апрацоўка '''$1'''
|
||||
[[Special:ConfirmAccounts|{{PLURAL:$1|запыту на стварэньне рахунку|запытаў на стварэньне рахунку|запытаў на стварэньне рахунку}}]]. '''Зьвярніце Вашую ўвагу!'''",
|
||||
'requestaccount-loginnotice' => "Каб атрымаць рахунак, Вам неабходна '''[[Special:RequestAccount|падаць запыт]]'''.",
|
||||
'right-confirmaccount' => 'прагляд [[Special:ConfirmAccounts|запытаў на стварэньне рахункаў]]',
|
||||
'right-requestips' => 'прагляд IP-адрасоў з якіх паступалі запыты на стварэньне рахункаў',
|
||||
'right-lookupcredentials' => 'прагляд [[Special:UserCredentials|пасьведчаньняў ўдзельнікаў]]',
|
||||
);
|
||||
|
||||
/** Bulgarian (български)
|
||||
* @author DCLXVI
|
||||
* @author Spiritia
|
||||
*/
|
||||
$messages['bg'] = array(
|
||||
'requestaccount-loginnotice' => "За да получите потребителска сметка, необходимо е да '''[[Special:RequestAccount|изпратите заявка]]'''.",
|
||||
);
|
||||
|
||||
/** Breton (brezhoneg)
|
||||
* @author Fohanno
|
||||
* @author Fulup
|
||||
* @author Y-M D
|
||||
*/
|
||||
$messages['br'] = array(
|
||||
'confirmaccount-newrequests' => "Er mare-mañ ez eus '''$1''' [[Special:ConfirmAccounts|goulenn kont{{PLURAL:$1||}}]] o vont en-dro.", # Fuzzy
|
||||
'requestaccount-loginnotice' => "Evit kaout ur gont implijer e rankit '''[[Special:RequestAccount|goulenn unan]]'''.",
|
||||
'right-confirmaccount' => "Gwelet [[Special:ConfirmAccounts|lostad ar c'hontoù goulennet]]",
|
||||
'right-requestips' => "Gwelet chomlec'hioù IP ar c'houlennerien pa vez pledet gant goulennoù krouiñ kontoù nevez.",
|
||||
'right-lookupcredentials' => 'Gwelet [[Special:UserCredentials|daveennoù an implijerien]]',
|
||||
);
|
||||
|
||||
/** Bosnian (bosanski)
|
||||
* @author CERminator
|
||||
*/
|
||||
$messages['bs'] = array(
|
||||
'requestaccount-loginnotice' => "Da biste korisnički račun, morate '''[[Special:RequestAccount|zahtijevati jedan]]'''.",
|
||||
);
|
||||
|
||||
/** Czech (česky)
|
||||
* @author Jkjk
|
||||
* @author Li-sung
|
||||
* @author Matěj Grabovský
|
||||
* @author Mormegil
|
||||
*/
|
||||
$messages['cs'] = array(
|
||||
'requestaccount-loginnotice' => "Chcete-li získat uživatelský účet, je třeba o něj '''[[Special:RequestAccount|požádat]]'''.",
|
||||
);
|
||||
|
||||
/** Danish (dansk)
|
||||
* @author Kaare
|
||||
*/
|
||||
$messages['da'] = array(
|
||||
'confirmaccount-newrequests' => "'''$1''' {{PLURAL:$1|åben kontoanmodning|åbne kontoanmodninger}} med bekræftet e-mail [[Special:ConfirmAccounts| venter på behandling]]. '''Din opmærksomhed er påkrævet!'''",
|
||||
'requestaccount-loginnotice' => "For at få en brugerkonto, skal du '''[[Special:RequestAccount|anmode om en]]'''.",
|
||||
'right-confirmaccount' => 'Vis [[Special:ConfirmAccounts|kontoanmodningskøen]]',
|
||||
'right-requestips' => 'Vis anmoderers IP-adresse mens der behandles kontoanmodninger',
|
||||
'right-lookupcredentials' => 'Vis [[Special:UserCredentials|brugeroplysninger]]',
|
||||
);
|
||||
|
||||
/** German (Deutsch)
|
||||
* @author Als-Holder
|
||||
* @author Kghbln
|
||||
* @author Leithian
|
||||
* @author MF-Warburg
|
||||
* @author Pill
|
||||
* @author Purodha
|
||||
* @author Raimond Spekking
|
||||
* @author Revolus
|
||||
* @author Rrosenfeld
|
||||
* @author The Evil IP address
|
||||
* @author Umherirrender
|
||||
*/
|
||||
$messages['de'] = array(
|
||||
'confirmaccount-newrequests' => "'''$1''' {{PLURAL:$1|[[Special:ConfirmAccounts|offener, E-Mail bestätigter Benutzerkontenantrag wartet]]|[[Special:ConfirmAccounts|offene, E-Mail bestätigte Benutzerkontenanträge warten]]}} auf Bearbeitung. '''Bitte kümmere dich darum.'''",
|
||||
'requestaccount-loginnotice' => "Um ein neues Benutzerkonto zu erhalten, musst du es '''[[Special:RequestAccount|beantragen]]'''.",
|
||||
'right-confirmaccount' => 'Die [[Special:ConfirmAccounts|Warteschlange der angefragten Benutzerkonten]] sehen',
|
||||
'right-requestips' => 'Die IP-Adresse des Anfragers für ein Benutzerkonto sehen',
|
||||
'right-lookupcredentials' => '[[Special:UserCredentials|Benutzerempfehlungsschreiben]] sehen',
|
||||
);
|
||||
|
||||
/** German (formal address) (Deutsch (Sie-Form))
|
||||
* @author Imre
|
||||
* @author Kghbln
|
||||
* @author The Evil IP address
|
||||
* @author Umherirrender
|
||||
*/
|
||||
$messages['de-formal'] = array(
|
||||
'confirmaccount-newrequests' => "'''$1''' {{PLURAL:$1|[[Special:ConfirmAccounts|offener, E-Mail bestätigter Benutzerkontenantrag wartet]]|[[Special:ConfirmAccounts|offene, E-Mail bestätigte Benutzerkontenanträge warten]]}} auf Bearbeitung. '''Bitte kümmern Sie sich darum.'''",
|
||||
'requestaccount-loginnotice' => "Um ein neues Benutzerkonto zu erhalten, müssen Sie es '''[[Special:RequestAccount|beantragen]]'''.",
|
||||
);
|
||||
|
||||
/** Zazaki (Zazaki)
|
||||
* @author Erdemaslancan
|
||||
*/
|
||||
$messages['diq'] = array(
|
||||
'right-confirmaccount' => '[[Special:ConfirmAccounts|Grub da hesab waştena]] vineno',
|
||||
'right-lookupcredentials' => '[[Special:UserCredentials|Referansanê karberan]] vineno',
|
||||
);
|
||||
|
||||
/** Lower Sorbian (dolnoserbski)
|
||||
* @author Michawiki
|
||||
*/
|
||||
$messages['dsb'] = array(
|
||||
'confirmaccount-newrequests' => "'''$1''' {{PLURAL:$1|pśez e-mail wobkšuśone|pśez e-mail wobkšuśonej|pśez e-mail wobkšuśone|pśez e-mail wobkšuśonych }} [[Special:ConfirmAccounts|{{PLURAL:$1|póžedanje na konto jo njedocynjone|póžedani na konśe stej njedocynjonej| póžedanja na konta su njedocynjone|póžedanjow na konta jo njedocynjone}}]]. '''Pšosym staraj wó to!'''",
|
||||
'requestaccount-loginnotice' => "Aby dostał wužywarske konto, musyš '''[[Special:RequestAccount|póžedanje na nje stajiś]]'''.",
|
||||
'right-confirmaccount' => '[[Special:ConfirmAccounts|Cakański rěd z pominanymi kontami]] se woglědaś',
|
||||
'right-requestips' => 'IP-adrese póžadarja se woglědaś, mjaztym až se pominane konta pśeźěłuju',
|
||||
'right-lookupcredentials' => '[[Special:UserCredentials|Wužywarske wopšawnjeńki]] se woglědaś',
|
||||
);
|
||||
|
||||
/** Esperanto (Esperanto)
|
||||
* @author Amikeco
|
||||
* @author Michawiki
|
||||
* @author Yekrats
|
||||
*/
|
||||
$messages['eo'] = array(
|
||||
'requestaccount-loginnotice' => "Akiri uzanto-konton, vi devas '''[[Special:RequestAccount|peti ĝin]]'''.",
|
||||
);
|
||||
|
||||
/** Spanish (español)
|
||||
* @author Armando-Martin
|
||||
* @author BicScope
|
||||
* @author Crazymadlover
|
||||
* @author Fitoschido
|
||||
* @author Imre
|
||||
* @author Lin linao
|
||||
* @author Locos epraix
|
||||
* @author Pertile
|
||||
* @author Sanbec
|
||||
* @author Translationista
|
||||
*/
|
||||
$messages['es'] = array(
|
||||
'confirmaccount-newrequests' => "'''$1''' correo electrónico abierto ha confirmado que [[Special:ConfirmAccounts|{{PLURAL:$1|solicitud de cuenta está pendiente|solicitudes de cuenta están pendientes}}]]. '''Se necesita su atención!'''",
|
||||
'requestaccount-loginnotice' => "Para obtener una cuenta de usuario, debes '''[[Special:RequestAccount|solicitar una]]'''.",
|
||||
'right-confirmaccount' => 'Consulte la [[Special:ConfirmAccounts|cola de solicitudes de cuenta]]',
|
||||
'right-requestips' => 'Ver la dirección IP del solicitante mientras se procesan las solicitudes de cuenta',
|
||||
'right-lookupcredentials' => 'Ver las [[Special:UserCredentials|credenciales del usuario]]',
|
||||
);
|
||||
|
||||
/** Finnish (suomi)
|
||||
* @author Centerlink
|
||||
* @author Cimon Avaro
|
||||
* @author Crt
|
||||
* @author Jaakonam
|
||||
* @author Mobe
|
||||
* @author Nike
|
||||
* @author Str4nd
|
||||
* @author Taleman
|
||||
* @author Varusmies
|
||||
*/
|
||||
$messages['fi'] = array(
|
||||
'confirmaccount-newrequests' => "Nyt on '''$1''' {{PLURAL:$1|avoin|avointa}} {{PLURAL:$1|[[Special:ConfirmAccounts|pyyntö]]|[[Special:ConfirmAccounts|pyyntöä]]}} käsiteltävänä.", # Fuzzy
|
||||
'requestaccount-loginnotice' => "Saadaksesi käyttäjätunnuksen on tehtävä '''[[Special:RequestAccount|käyttäjätunnuspyyntö]]'''.",
|
||||
'right-confirmaccount' => 'Nähdä [[Special:ConfirmAccounts|listan pyydetyistä tunnuksista]]',
|
||||
'right-requestips' => 'Nähdä hakijan IP-osoitteet käyttäjätilejä käsiteltäessä',
|
||||
'right-lookupcredentials' => 'Nähdä [[Special:UserCredentials|käyttäjän luotettavuustiedot]]',
|
||||
);
|
||||
|
||||
/** French (français)
|
||||
* @author Crochet.david
|
||||
* @author Dereckson
|
||||
* @author Grondin
|
||||
* @author IAlex
|
||||
* @author Louperivois
|
||||
* @author McDutchie
|
||||
* @author Meithal
|
||||
* @author Peter17
|
||||
* @author PieRRoMaN
|
||||
* @author Sherbrooke
|
||||
* @author Urhixidur
|
||||
* @author Zetud
|
||||
*/
|
||||
$messages['fr'] = array(
|
||||
'confirmaccount-newrequests' => "Il y a actuellement '''$1''' [[Special:ConfirmAccounts|demande{{PLURAL:$1||s}} de compte]] en cours. '''Votre attention est nécessaire !'''",
|
||||
'requestaccount-loginnotice' => "Pour obtenir un compte utilisateur, vous devez en faire '''[[Special:RequestAccount|la demande]]'''.",
|
||||
'right-confirmaccount' => 'Voir la [[Special:ConfirmAccounts|file des demandes de compte]]',
|
||||
'right-requestips' => 'Voir les adresses IP des demandeurs lors du traitement des demandes de nouveau comptes',
|
||||
'right-lookupcredentials' => 'Voir les [[Special:UserCredentials|références des utilisateurs]]',
|
||||
);
|
||||
|
||||
/** Franco-Provençal (arpetan)
|
||||
* @author ChrisPtDe
|
||||
*/
|
||||
$messages['frp'] = array(
|
||||
'confirmaccount-newrequests' => "Ora, y at '''$1''' [[Special:ConfirmAccounts|demand{{PLURAL:$1|a|es}} de compto usanciér]] en cors. '''Voutra atencion est nècèssèra !'''",
|
||||
'requestaccount-loginnotice' => "Por avêr un compto usanciér, vos en dête fâre la '''[[Special:RequestAccount|demanda]]'''.",
|
||||
);
|
||||
|
||||
/** Galician (galego)
|
||||
* @author Alma
|
||||
* @author Elisardojm
|
||||
* @author Toliño
|
||||
* @author Xosé
|
||||
*/
|
||||
$messages['gl'] = array(
|
||||
'confirmaccount-newrequests' => "Actualmente hai '''$1''' [[Special:ConfirmAccounts|{{PLURAL:$1|solicitude de conta pendente|solicitudes de contas pendentes}}]]. '''Cómpre a súa atención!'''",
|
||||
'requestaccount-loginnotice' => "Para obter unha conta de usuario ten que '''[[Special:RequestAccount|solicitar unha]]'''.",
|
||||
'right-confirmaccount' => 'Ver a [[Special:ConfirmAccounts|cola coas solicitudes de contas]]',
|
||||
'right-requestips' => 'Ver os enderezos IP que solicitan contas',
|
||||
'right-lookupcredentials' => 'Ver as [[Special:UserCredentials|credenciais de usuario]]',
|
||||
);
|
||||
|
||||
/** Swiss German (Alemannisch)
|
||||
* @author Als-Chlämens
|
||||
* @author Als-Holder
|
||||
*/
|
||||
$messages['gsw'] = array(
|
||||
'confirmaccount-newrequests' => "'''$1''' {{PLURAL:$1|[[Special:ConfirmAccounts|ufige, E-Mail bstätigte Benutzerkontenaatrag wartet]]|[[Special:ConfirmAccounts|ufigi, E-Mail bstätigti Benutzerkontenaaträg warten]]}} uf Bearbeitig. '''Bitte due dich drum chümmre.'''",
|
||||
'requestaccount-loginnotice' => "Go ne nej Benutzerkonto iberchu muesch e '''[[Special:RequestAccount|Aatrag stelle]]'''.",
|
||||
'right-confirmaccount' => '[[Special:ConfirmAccounts|Lischt mit beaatraite Benutzerkonte]] aaluege',
|
||||
'right-requestips' => 'D IP-Adräss vum Aatragsteller aaluege, derwylscht dr Aatrag bearbeitet wird',
|
||||
'right-lookupcredentials' => '[[Special:UserCredentials|Zyygnis vum Benutzer]] aaluege',
|
||||
);
|
||||
|
||||
/** Hebrew (עברית)
|
||||
* @author Amire80
|
||||
* @author Rotemliss
|
||||
* @author StuB
|
||||
* @author YaronSh
|
||||
*/
|
||||
$messages['he'] = array(
|
||||
'confirmaccount-newrequests' => "יש {{PLURAL:$1|[[Special:ConfirmAccounts|בקשה פתוחה ממתינה '''אחת''' לפתוח חשבון]], עם כתובת דואר אלקטרוני מאושרת שממתינה|'''$1''' [[Special:ConfirmAccounts|בקשות פתוחות לפתוח חשבונות]], עם כתובות דואר אלקטרוני מאושרות שממתינות}} לאישור. ''תשומת לבך נדרשת!''",
|
||||
'requestaccount-loginnotice' => "כדי לקבל חשבון משתמש, עליכם '''[[Special:RequestAccount|לבקש אחד כזה]]'''.",
|
||||
'right-confirmaccount' => 'צפייה ב[[Special:ConfirmAccounts|תור עם החשבונות הדרושים]]',
|
||||
'right-requestips' => 'לצפות בכתובות IP של המבקשים בזמן עיבוד בקשות לפתוח חשבון',
|
||||
'right-lookupcredentials' => 'צפייה ב[[Special:UserCredentials|הרשאות המשתמש]]',
|
||||
);
|
||||
|
||||
/** Hindi (हिन्दी)
|
||||
* @author Kaustubh
|
||||
* @author Kiranmayee
|
||||
* @author आलोक
|
||||
*/
|
||||
$messages['hi'] = array(
|
||||
'requestaccount-loginnotice' => "सदस्य खाता पाने के लिये आप अपनी '''[[Special:RequestAccount|माँग पंजिकृत करें]]'''।",
|
||||
);
|
||||
|
||||
/** Croatian (hrvatski)
|
||||
* @author Dalibor Bosits
|
||||
* @author Dnik
|
||||
* @author Ex13
|
||||
* @author SpeedyGonsales
|
||||
*/
|
||||
$messages['hr'] = array(
|
||||
'confirmaccount-newrequests' => "u tijeku '''$1''' e-mailom {{PLURAL:$1|potvrđen [[Special:ConfirmAccounts|zahtjev za računom]]|potvrđenih [[Special:ConfirmAccounts|zahtjeva za računom]]}}", # Fuzzy
|
||||
'requestaccount-loginnotice' => "Da bi dobili suradnički račun, trebate ga '''[[Special:RequestAccount|zatražiti]]'''.",
|
||||
);
|
||||
|
||||
/** Upper Sorbian (hornjoserbsce)
|
||||
* @author Michawiki
|
||||
*/
|
||||
$messages['hsb'] = array(
|
||||
'confirmaccount-newrequests' => "{{PLURAL:$1|Čaka|Čakatej|Čakaja|Čaka}} tuchwilu '''$1''' přez e-mejlu [[Special:ConfirmAccounts|{{PLURAL:$1|wobkrućene kontowe požadanje|wobkrućenej kontowej požadani|wobkrućene kontowe požadanja|wobkrućenych kontowych požadanjow}}]]. '''Prošu staraj so wo to!'''",
|
||||
'requestaccount-loginnotice' => "Zo by wužiwarske konto dóstał, dyrbiš wo nje '''[[Special:RequestAccount|prosyć]]'''.",
|
||||
'right-confirmaccount' => '[[Special:ConfirmAccounts|Čakanski rynk z požadanymi kontami]] sej wobhladać',
|
||||
'right-requestips' => 'IP-adresy požadarja sej wobhladać, mjeztym zo so požadane konta předźěłuja',
|
||||
'right-lookupcredentials' => '[[Special:UserCredentials|Wužiwarske woprawnjenki]] sej wobhladać',
|
||||
);
|
||||
|
||||
/** Hungarian (magyar)
|
||||
* @author Dani
|
||||
* @author Dj
|
||||
* @author Dorgan
|
||||
* @author Glanthor Reviol
|
||||
* @author Tgr
|
||||
*/
|
||||
$messages['hu'] = array(
|
||||
'confirmaccount-newrequests' => "'''$1''' e-mail megerősített [[Special:ConfirmAccounts| fiók kérés van függőben]]. '''Figyelmet igényel!'''",
|
||||
'requestaccount-loginnotice' => "Ha felhasználói fiókot szeretnél, akkor '''[[Special:RequestAccount|kérned kell egyet]]'''.",
|
||||
'right-confirmaccount' => '[[Special:ConfirmAccounts|kért felhasználói fiókok várakozási sorának]] megtekintése',
|
||||
'right-requestips' => 'az igénylők IP-címeinek megtekintése a kért fiókok feldolgozása közben',
|
||||
'right-lookupcredentials' => '[[Special:UserCredentials|felhasználói azonosító információk]] megjelenítése',
|
||||
);
|
||||
|
||||
/** Interlingua (interlingua)
|
||||
* @author McDutchie
|
||||
*/
|
||||
$messages['ia'] = array(
|
||||
'confirmaccount-newrequests' => "Es pendente '''$1''' [[Special:ConfirmAccounts|{{PLURAL:$1|requesta|requestas}} de conto]] aperte e confirmate via e-mail. '''Tu attention es necessari!'''",
|
||||
'requestaccount-loginnotice' => "Pro obtener un conto de usator, tu debe '''[[Special:RequestAccount|requestar un]]'''.",
|
||||
'right-confirmaccount' => 'Vider le [[Special:ConfirmAccounts|cauda con requestas de conto]]',
|
||||
'right-requestips' => 'Vider le adresses IP del requestatores durante le tractamento de requestas de conto',
|
||||
'right-lookupcredentials' => 'Vider le [[Special:UserCredentials|credentiales de usatores]]',
|
||||
);
|
||||
|
||||
/** Indonesian (Bahasa Indonesia)
|
||||
* @author Bennylin
|
||||
* @author Irwangatot
|
||||
* @author IvanLanin
|
||||
* @author Iwan Novirion
|
||||
* @author Rex
|
||||
*/
|
||||
$messages['id'] = array(
|
||||
'confirmaccount-newrequests' => "Terdapat '''$1''' antrean [[Special:ConfirmAccounts|{{PLURAL:$1|permintaan|permintaan}} akun]] yang surelnya telah dikonfirmasi.", # Fuzzy
|
||||
'requestaccount-loginnotice' => "Untuk mendapatkan sebuah akun pengguna, Anda harus '''[[Special:RequestAccount|mengajukannya]]'''.",
|
||||
'right-confirmaccount' => 'Lihat [[Special:ConfirmAccounts|antrean peminta akun]]',
|
||||
'right-requestips' => 'Lihat Alamat IP pemohon selama proses permohonan akun',
|
||||
'right-lookupcredentials' => 'Lihat [[Special:UserCredentials|pengguna Kredensial]]',
|
||||
);
|
||||
|
||||
/** Icelandic (íslenska)
|
||||
* @author S.Örvarr.S
|
||||
* @author Ævar Arnfjörð Bjarmason
|
||||
*/
|
||||
$messages['is'] = array(
|
||||
'confirmaccount-newrequests' => "'''$1''' [[Special:ConfirmAccounts|{{PLURAL:$1|notandabeðni|notandabeðnir}}]] {{PLURAL:$1|með staðfest netfang bíður samþykkis|með staðfest netföng bíða samþykkis}}", # Fuzzy
|
||||
'requestaccount-loginnotice' => "Ef þú ert ekki þegar með aðgang verður þú að '''[[Special:RequestAccount|sækja um einn slíkan]]'''.",
|
||||
);
|
||||
|
||||
/** Italian (italiano)
|
||||
* @author Beta16
|
||||
* @author Darth Kule
|
||||
* @author Melos
|
||||
* @author Pietrodn
|
||||
* @author Stefano-c
|
||||
*/
|
||||
$messages['it'] = array(
|
||||
'confirmaccount-newrequests' => "'''$1''' e-mail di conferma [[Special:ConfirmAccounts|per account {{PLURAL:$1|è|sono}} in attesa]]. '''È necessaria la tua attenzione!'''",
|
||||
'requestaccount-loginnotice' => "Per ottenere un account utente, è necessario '''[[Special:RequestAccount|richiederne uno]]'''.",
|
||||
'right-confirmaccount' => 'Visualizza la [[Special:ConfirmAccounts|coda gli account richiesti]]',
|
||||
'right-requestips' => 'Visualizza gli indirizzi IP del richiedente mentre processa gli account richiesti',
|
||||
'right-lookupcredentials' => 'Visualizza [[Special:UserCredentials|credenziali utente]]',
|
||||
);
|
||||
|
||||
/** Japanese (日本語)
|
||||
* @author Aotake
|
||||
* @author Fryed-peach
|
||||
* @author JtFuruhata
|
||||
* @author Schu
|
||||
* @author Shirayuki
|
||||
* @author 青子守歌
|
||||
*/
|
||||
$messages['ja'] = array(
|
||||
'confirmaccount-newrequests' => "現在、'''$1個'''のメール認証済み{{PLURAL:$1|[[Special:ConfirmAccounts|アカウント申請]]}}が承認待ちになっています。'''注意が必要です!'''",
|
||||
'requestaccount-loginnotice' => "利用者アカウントを取得するには、'''[[Special:RequestAccount|アカウント登録申請]]'''をしてください。",
|
||||
'right-confirmaccount' => '[[Special:ConfirmAccounts|アカウント申請キュー]]を閲覧',
|
||||
'right-requestips' => 'アカウント申請の処理中に申請者のIPアドレスを閲覧',
|
||||
'right-lookupcredentials' => '[[Special:UserCredentials|利用者信頼情報]]を閲覧',
|
||||
);
|
||||
|
||||
/** Jamaican Creole English (Patois)
|
||||
* @author Yocahuna
|
||||
*/
|
||||
$messages['jam'] = array(
|
||||
'confirmaccount-newrequests' => "'''$1''' opn e-miel-kanfoerm [[Special:ConfirmAccounts|akount {{PLURAL:$1|rikwes|rikwes}}]] pendin", # Fuzzy
|
||||
'requestaccount-loginnotice' => "Fi abtien a yuuza akount, yu fi '''[[Special:RequestAccount|rikwes wan]]'''.",
|
||||
);
|
||||
|
||||
/** Javanese (Basa Jawa)
|
||||
* @author Meursault2004
|
||||
* @author Pras
|
||||
*/
|
||||
$messages['jv'] = array(
|
||||
'requestaccount-loginnotice' => "Supaya bisa olèh rékening panganggo, panjenengan kudu '''[[Special:RequestAccount|nyuwun iku]]'''.",
|
||||
);
|
||||
|
||||
/** Khmer (ភាសាខ្មែរ)
|
||||
* @author Chhorran
|
||||
* @author Lovekhmer
|
||||
* @author Sovichet
|
||||
* @author Thearith
|
||||
* @author គីមស៊្រុន
|
||||
* @author វ័ណថារិទ្ធ
|
||||
*/
|
||||
$messages['km'] = array(
|
||||
'requestaccount-loginnotice' => "ដើម្បីទទួលបានគណនីអ្នកប្រើប្រាស់ អ្នកត្រូវតែ'''[[Special:RequestAccount|ស្នើសុំគណនី]]'''។",
|
||||
);
|
||||
|
||||
/** Colognian (Ripoarisch)
|
||||
* @author Purodha
|
||||
*/
|
||||
$messages['ksh'] = array(
|
||||
'confirmaccount-newrequests' => '{{PLURAL:$1|Ein|\'\'\'$1\'\'\'|Kein}} unjedonn [[Special:ConfirmAccounts|{{PLURAL:$1|Aanfrooch|Aanfroore|Aanfroore}}]] met beschtääteschte <i lang="en">e-mail</i>-Addräß {{PLURAL:$1|es|sin|sin}} am waade.',
|
||||
'requestaccount-loginnotice' => "Öm ene Zohjang ze krijje, donn '''[[Special:RequestAccount|noh einem froore]]'''.",
|
||||
'right-confirmaccount' => 'De [[Special:ConfirmAccounts|Schlang met de aanjefroochte Zohjäng]] beloore',
|
||||
'right-requestips' => 'De jewönschte Neu_Metmaacher ier <code lang="en">IP-</code>Addräß aanloore beim Aanfroore beärbeede',
|
||||
'right-lookupcredentials' => 'De [[Special:UserCredentials|Nohwiise]] för Metmaacher aanloore',
|
||||
);
|
||||
|
||||
/** Luxembourgish (Lëtzebuergesch)
|
||||
* @author Les Meloures
|
||||
* @author Robby
|
||||
*/
|
||||
$messages['lb'] = array(
|
||||
'confirmaccount-newrequests' => "'''$1''' open, per E-Mail confirméiert, [[Special:ConfirmAccounts|account {{PLURAL:$1|Ufro|Ufroen}}]] déi drop {{PLURAL:$1|waart|waarden}} beäntwert ze ginn. '''Är Mataarbecht gëtt gebraucht!'''",
|
||||
'requestaccount-loginnotice' => "Fir e Benotzerkont ze kréien, musst Dir '''[[Special:RequestAccount|een ufroen]]'''.",
|
||||
'right-confirmaccount' => "D'[[Special:ConfirmAccounts|Queue mat den ugefrote Benotzerkonte]] kucken",
|
||||
'right-requestips' => "D'IP-Adress vun där d'Ufro koum uweise wann d'Ufro fir e Benotzerkont verschafft gëtt",
|
||||
'right-lookupcredentials' => '[[Special:UserCredentials|Referenze vun de Benotzer]] kucken',
|
||||
);
|
||||
|
||||
/** Lezghian (лезги)
|
||||
* @author Migraghvi
|
||||
*/
|
||||
$messages['lez'] = array(
|
||||
'requestaccount-loginnotice' => 'Иштиракчидин аккаунт къачун патал квез ам [[Special:RequestAccount|тIалабиз герек я]] .',
|
||||
);
|
||||
|
||||
/** Limburgish (Limburgs)
|
||||
* @author Pahles
|
||||
*/
|
||||
$messages['li'] = array(
|
||||
'confirmaccount-newrequests' => "Dao {{PLURAL:$1|steit|stoon}} '''$1''' [[Special:ConfirmAccounts|{{PLURAL:$1|gebroekersaanvraog|gebroekersaanvraoge}}]] aope. '''Dien aandach is nujig!'''",
|
||||
'requestaccount-loginnotice' => "Um 'n gebroekersaccount te kriege mós te '''[[Special:RequestAccount|'ne aanvraog doon]]'''",
|
||||
'right-confirmaccount' => '[[Special:CorfirmAccounts|Wachrie mit gebroekersaanvraoge]] betrachte', # Fuzzy
|
||||
'right-requestips' => "De IP-adresse van aanvraogers betrachte bie 't verwirke van gebroekersaanvraage",
|
||||
'right-lookupcredentials' => '[[Special:UserCredentials|Gebroekersreferenties]] betrachte',
|
||||
);
|
||||
|
||||
/** Basa Banyumasan (Basa Banyumasan)
|
||||
* @author StefanusRA
|
||||
*/
|
||||
$messages['map-bms'] = array(
|
||||
'confirmaccount-newrequests' => "Ana '''$1''' antrean [[Special:ConfirmAccounts|{{PLURAL:$1|penjalukan|penjalukan}} akun]] sing imel-e uwis dikonfirmasi. '''Gageyan diproses!'''",
|
||||
'requestaccount-loginnotice' => "Ben teyeng nduwe akun panganggo, Rika kudu '''[[Special:RequestAccount|njaluk akun]]'''.",
|
||||
'right-confirmaccount' => 'Deleng [[Special:ConfirmAccounts|antrean penjalukan akun]]',
|
||||
'right-requestips' => 'Deleng Alamat IP-ne sing njaluk akun selama proses penjalukan akun',
|
||||
'right-lookupcredentials' => 'Deleng [[Special:UserCredentials|panganggo Kredensial]]',
|
||||
);
|
||||
|
||||
/** Macedonian (македонски)
|
||||
* @author Bjankuloski06
|
||||
* @author Brest
|
||||
*/
|
||||
$messages['mk'] = array(
|
||||
'confirmaccount-newrequests' => "Има '''$1''' [[Special:ConfirmAccounts|{{PLURAL:$1|отворено барање за сметка|отворени барања за сметка}}]] во исчекување. '''Потребно е вашето внимание!'''",
|
||||
'requestaccount-loginnotice' => "За да добиете корисничка сметка, морате да '''[[Special:RequestAccount|поднесете барање]]'''.",
|
||||
'right-confirmaccount' => 'Погледајте ја [[Special:ConfirmAccounts|редицата со побарани сметки]]',
|
||||
'right-requestips' => 'Прегледување на IP-адресите на барателот при работата на побарани сметки',
|
||||
'right-lookupcredentials' => 'Погледајте ги [[Special:UserCredentials|препораките за корисникот]]',
|
||||
);
|
||||
|
||||
/** Malayalam (മലയാളം)
|
||||
* @author Jacob.jose
|
||||
* @author Junaidpv
|
||||
* @author Praveenp
|
||||
* @author Shijualex
|
||||
*/
|
||||
$messages['ml'] = array(
|
||||
'confirmaccount-newrequests' => "ഇമെയിൽ വിലാസം സ്ഥിരീകരിക്കപ്പെട്ട '''$1''' {{PLURAL:$1|[[Special:ConfirmAccounts|അംഗത്വത്തിനായുള്ള അഭ്യർത്ഥന]]|[[Special:ConfirmAccounts|അംഗത്വത്തിനായുള്ള അഭ്യർത്ഥനകൾ]]}} പെൻഡിംങ്ങാണ്.", # Fuzzy
|
||||
'requestaccount-loginnotice' => "ഉപയോക്തൃ അംഗത്വം ലഭിക്കുന്നതിനായി താങ്കൾ '''[[Special:RequestAccount|ഉപയോക്തൃഅംഗത്വത്തിനായി അഭ്യർത്ഥിക്കണം]]'''.",
|
||||
);
|
||||
|
||||
/** Marathi (मराठी)
|
||||
* @author Htt
|
||||
* @author Kaustubh
|
||||
* @author Mahitgar
|
||||
*/
|
||||
$messages['mr'] = array(
|
||||
'confirmaccount-newrequests' => "'''$1''' इमेल पत्ता तपासलेला आहे {{PLURAL:$1|[[Special:ConfirmAccounts|खात्याची मागणी]]|[[Special:ConfirmAccounts|खात्यांची मागणी]]}} शिल्लक", # Fuzzy
|
||||
'requestaccount-loginnotice' => "सदस्य खाते मिळविण्यासाठी तुम्ही तुमची '''[[Special:RequestAccount|मागणी नोंदवा]]'''.",
|
||||
);
|
||||
|
||||
/** Malay (Bahasa Melayu)
|
||||
* @author Anakmalaysia
|
||||
*/
|
||||
$messages['ms'] = array(
|
||||
'confirmaccount-newrequests' => "'''$1''' [[Special:ConfirmAccounts|permintaan akaun]] yang disahkan oleh pembukaan e-mel sedang menunggu. '''Perhatian anda diperlukan!'''",
|
||||
'requestaccount-loginnotice' => "Untuk memperoleh akaun pengguna, anda mesti '''[[Special:RequestAccount|membuat permohonan]]'''.",
|
||||
'right-confirmaccount' => 'Melihat [[Special:ConfirmAccounts|baris gilir dengan akaun-akaun yang dimohon]]',
|
||||
'right-requestips' => 'Melihat alamat-alamat IP pemohon ketika memproseskan akaun-akaun yang dimohon',
|
||||
'right-lookupcredentials' => 'Melihat [[Special:UserCredentials|kelayakan pengguna]]',
|
||||
);
|
||||
|
||||
/** Maltese (Malti)
|
||||
* @author Chrisportelli
|
||||
*/
|
||||
$messages['mt'] = array(
|
||||
'confirmaccount-newrequests' => "'''$1''' indirizzi elettroniċi ta' konferma [[Special:ConfirmAccounts|kull kont {{PLURAL:$1hija|huma}} pendenti]]. '''L-attenzjoni tiegħek hija neċessarja!'''",
|
||||
'requestaccount-loginnotice' => "Sabiex tikseb kont tal-utent, trid '''[[Special:RequestAccount|titlob wieħed]]'''.",
|
||||
'right-confirmaccount' => "Jara l-[[Special:ConfirmAccounts|kju ta' kontijiet rikjesti]]",
|
||||
'right-requestips' => 'Jara l-indirizz IP tar-rikjedent waqt li jipproċessa l-kontijiet rikjesti',
|
||||
'right-lookupcredentials' => 'Jara l-[[Special:UserCredentials|kredenzjali tal-utent]]',
|
||||
);
|
||||
|
||||
/** Norwegian Bokmål (norsk (bokmål))
|
||||
* @author Event
|
||||
* @author Harald Khan
|
||||
* @author Laaknor
|
||||
* @author Nghtwlkr
|
||||
*/
|
||||
$messages['nb'] = array(
|
||||
'confirmaccount-newrequests' => "Det er foreløpig '''$1''' {{PLURAL:$1|åpen [[Special:ConfirmAccounts|kontoforespørsel]]|åpne [[Special:ConfirmAccounts|kontoforespørsler]]}}.", # Fuzzy
|
||||
'requestaccount-loginnotice' => "For å få en brukerkonto må du '''[[Special:RequestAccount|etterspørre en]]'''.",
|
||||
'right-confirmaccount' => 'Vis [[Special:ConfirmAccounts|køen av kontosøknader]]',
|
||||
'right-requestips' => 'Vis søkerenes IP-adresser mens man behandler kontosøknadene',
|
||||
'right-lookupcredentials' => 'Vis [[Special:UserCredentials|brukerattester]]',
|
||||
);
|
||||
|
||||
/** Dutch (Nederlands)
|
||||
* @author Annabel
|
||||
* @author SPQRobin
|
||||
* @author Siebrand
|
||||
*/
|
||||
$messages['nl'] = array(
|
||||
'confirmaccount-newrequests' => "Er {{PLURAL:$1|staat|staan}} '''$1''' [[Special:ConfirmAccounts|{{PLURAL:$1|gebruikersaanvraag|gebruikersaanvragen}}]] open. '''Uw aandacht is nodig!'''",
|
||||
'requestaccount-loginnotice' => "Om een gebruiker te krijgen, moet u '''[[Special:RequestAccount|een aanvraag doen]]'''.",
|
||||
'right-confirmaccount' => '[[Special:ConfirmAccounts|Wachtrij met gebruikersaanvragen]] bekijken',
|
||||
'right-requestips' => 'De IP-adressen van aanvragers bekijken bij het verwerken bij het verwerken van gebruikersaanvragen',
|
||||
'right-lookupcredentials' => '[[Special:UserCredentials|gebruikersreferenties]] bekijken',
|
||||
);
|
||||
|
||||
/** Norwegian Nynorsk (norsk (nynorsk))
|
||||
* @author Gunnernett
|
||||
* @author Harald Khan
|
||||
* @author Jon Harald Søby
|
||||
* @author Njardarlogar
|
||||
*/
|
||||
$messages['nn'] = array(
|
||||
'confirmaccount-newrequests' => "Det finst for tida {{PLURAL:$1|'''éin''' open [[Special:ConfirmAccounts|kontoførespurnad]]|'''$1''' opne [[Special:ConfirmAccounts|kontoførespurnader]]}}.", # Fuzzy
|
||||
'requestaccount-loginnotice' => "For å få ein brukarkonto må du '''[[Special:RequestAccount|be om ein]]'''.",
|
||||
'right-confirmaccount' => 'Vis [[Special:ConfirmAccounts|køen av kontosøknader]]',
|
||||
'right-requestips' => 'Vis søkjaren sine IP-adresser medan kontosøknadene er til handsaming',
|
||||
'right-lookupcredentials' => 'Vis [[Special:UserCredentials|brukarattestar]]',
|
||||
);
|
||||
|
||||
/** Occitan (occitan)
|
||||
* @author Cedric31
|
||||
*/
|
||||
$messages['oc'] = array(
|
||||
'confirmaccount-newrequests' => "Actualament i a '''$1''' {{PLURAL:$1|[[Special:ConfirmAccounts|demanda de compte]]|[[Special:ConfirmAccounts|demandas de compte]]}} en cors.", # Fuzzy
|
||||
'requestaccount-loginnotice' => "Per obténer un compte d'utilizaire, vos ne cal far '''[[Special:RequestAccount|la demanda]]'''.",
|
||||
'right-confirmaccount' => 'Vejatz la [[Special:ConfirmAccounts|fila de las demandas de compte]]',
|
||||
'right-requestips' => 'Vejatz las adreças IP dels demandaires al moment del tractament de las demandas de comptes novèls',
|
||||
'right-lookupcredentials' => 'Vejatz las [[Special:UserCredentials|referéncias dels utilizaires]]',
|
||||
);
|
||||
|
||||
/** Polish (polski)
|
||||
* @author Derbeth
|
||||
* @author Equadus
|
||||
* @author Leinad
|
||||
* @author Maikking
|
||||
* @author Masti
|
||||
* @author McMonster
|
||||
* @author Sp5uhe
|
||||
* @author ToSter
|
||||
* @author Wpedzich
|
||||
*/
|
||||
$messages['pl'] = array(
|
||||
'confirmaccount-newrequests' => "{{PLURAL:$1|Jest '''$1''' [[Special:ConfirmAccounts|oczekujący wniosek]]|Są '''$1''' [[Special:ConfirmAccounts|oczekujące wnioski]]|Jest '''$1''' [[Special:ConfirmAccounts|oczekujących wniosków]]}}, z potwierdzonym adresem e‐mail. '''Konieczna jest Twoja ingerencja!'''",
|
||||
'requestaccount-loginnotice' => "By uzyskać konto użytkownika musisz '''[[Special:RequestAccount|złożyć wniosek]]'''.",
|
||||
'right-confirmaccount' => 'Przeglądanie [[Special:ConfirmAccounts|kolejki z wnioskami o założenie konta]]',
|
||||
'right-requestips' => 'Przeglądanie adresów IP wnioskodawców podczas przetwarzania ich wniosków o założenie konta',
|
||||
'right-lookupcredentials' => 'Przeglądanie [[Special:UserCredentials|referencji użytkowników]]',
|
||||
);
|
||||
|
||||
/** Piedmontese (Piemontèis)
|
||||
* @author Borichèt
|
||||
* @author Bèrto 'd Sèra
|
||||
* @author Dragonòt
|
||||
*/
|
||||
$messages['pms'] = array(
|
||||
'confirmaccount-newrequests' => "'''$1''' mëssagi ch'a speto [[Special:ConfirmAccounts|{{PLURAL:$1|d'arcesta ëd cont confermà|d'arceste ëd cont confermà}}]]. '''A-i é dabzògn ëd soa atension!'''",
|
||||
'requestaccount-loginnotice' => "Për deurb-se un sò cont utent, a venta '''[[Special:RequestAccount|ch<nowiki>'</nowiki>a në ciama un]]'''.",
|
||||
'right-confirmaccount' => 'Vardé la [[Special:ConfirmAccounts|coa con ij cont ciamà]]',
|
||||
'right-requestips' => "Vardé j'adrësse IP dël ciamant durant ël tratament dij cont ciamà",
|
||||
'right-lookupcredentials' => 'Visualisa [[Special:UserCredentials|credensiaj utent]]',
|
||||
);
|
||||
|
||||
/** Portuguese (português)
|
||||
* @author Giro720
|
||||
* @author Hamilton Abreu
|
||||
* @author Lijealso
|
||||
* @author Malafaya
|
||||
* @author Waldir
|
||||
*/
|
||||
$messages['pt'] = array(
|
||||
'confirmaccount-newrequests' => "Há {{PLURAL:$1|'''um''' [[Special:ConfirmAccounts|pedido de conta]]|'''$1''' [[Special:ConfirmAccounts|pedidos de conta]]}} em aberto com correio electrónico confirmado. '''É necessária a sua atenção!'''",
|
||||
'requestaccount-loginnotice' => "Para obter uma conta de utilizador, deverá '''[[Special:RequestAccount|pedi-la]]'''.",
|
||||
'right-confirmaccount' => 'Ver a [[Special:ConfirmAccounts|fila de contas pedidas]]',
|
||||
'right-requestips' => 'Ver os endereços IP do requerente ao processar contas pedidas',
|
||||
'right-lookupcredentials' => 'Ver [[Special:UserCredentials|credenciais de utilizador]]',
|
||||
);
|
||||
|
||||
/** Brazilian Portuguese (português do Brasil)
|
||||
* @author Eduardo.mps
|
||||
* @author Giro720
|
||||
* @author Helder.wiki
|
||||
* @author Heldergeovane
|
||||
* @author Luckas Blade
|
||||
* @author 555
|
||||
*/
|
||||
$messages['pt-br'] = array(
|
||||
'confirmaccount-newrequests' => "Há, neste momento, '''$1''' [[Special:ConfirmAccounts|{{PLURAL:$1|solicitação|solicitações}} pendentes de contas]]. '''Seus cuidados são necessários!''",
|
||||
'requestaccount-loginnotice' => "Para ter uma conta de usuário, será necessário '''[[Special:RequestAccount|solicitá-la]]'''.",
|
||||
'right-confirmaccount' => 'Ver a [[Special:ConfirmAccounts|fila de contas solicitadas]]',
|
||||
'right-requestips' => 'Ver os endereços IP do requerente durante a gestão de contas pedidas',
|
||||
'right-lookupcredentials' => 'Ver [[Special:UserCredentials|credenciais de usuário]]',
|
||||
);
|
||||
|
||||
/** Russian (русский)
|
||||
* @author Ferrer
|
||||
* @author Ignatus
|
||||
* @author Kaganer
|
||||
* @author Kv75
|
||||
* @author Lockal
|
||||
* @author MaxSem
|
||||
* @author Rubin
|
||||
* @author Sasha Blashenkov
|
||||
* @author Александр Сигачёв
|
||||
*/
|
||||
$messages['ru'] = array(
|
||||
'confirmaccount-newrequests' => "$1 {{PLURAL:$1|[[Special:ConfirmAccounts|открытое письмо подтверждено]]|[[Special:ConfirmAccounts|открытых письма подтверждены]]|[[Special:ConfirmAccounts|открытых писем подтверждены]]}}. '''Обратите ваше внимание!'''",
|
||||
'requestaccount-loginnotice' => 'Чтобы получить учётную запись, вы должны её [[Special:RequestAccount|запросить]].',
|
||||
'right-confirmaccount' => 'просмотр [[Special:ConfirmAccounts|запросов на создание учётных записей]]',
|
||||
'right-requestips' => 'Просмотр IP-адресов авторов запросов на создание учётных записей',
|
||||
'right-lookupcredentials' => 'просмотр [[Special:UserCredentials|удостоверяющей информации об участниках]]',
|
||||
);
|
||||
|
||||
/** Slovak (slovenčina)
|
||||
* @author Helix84
|
||||
* @author Teslaton
|
||||
*/
|
||||
$messages['sk'] = array(
|
||||
'confirmaccount-newrequests' => "Momentálne {{PLURAL:$1|je jedna otvorená|sú '''$1''' otvorené|je '''$1''' otvorených}} [[Special:ConfirmAccounts|{{PLURAL:$1|žiadosť o účet|žiadosti o účet|žiadostí o účet}}]]. '''Vyžaduje sa vaša pozornosť!'''",
|
||||
'requestaccount-loginnotice' => "Aby ste dostali používateľský účet, musíte '''[[Special:RequestAccount|oň požiadať]]'''.",
|
||||
'right-confirmaccount' => 'Zobraziť [[Special:ConfirmAccounts|front žiadostí o účet]]',
|
||||
'right-requestips' => 'Zobraziť IP adresu žiadateľa pri spracovaní žiadostí o účet',
|
||||
'right-lookupcredentials' => 'Zobraziť [[Special:UserCredentials|údaje používateľa]]',
|
||||
);
|
||||
|
||||
/** Seeltersk (Seeltersk)
|
||||
* @author Pyt
|
||||
*/
|
||||
$messages['stq'] = array(
|
||||
'confirmaccount-newrequests' => "'''$1''' {{PLURAL:$1|[[Special:ConfirmAccounts|eepenen, E-Mail bestäätigden Benutserkontenandraach täift]]|[[Special:ConfirmAccounts|eepene, E-Mail bestäätigde Benutserkontenandraage täiwe]]}} ap Beoarbaidenge.", # Fuzzy
|
||||
'requestaccount-loginnotice' => "Uum n näi Benutserkonto tou kriegen, moast du
|
||||
der uum '''[[{{ns:special}}:RequestAccount|fräigje]]'''.", # Fuzzy
|
||||
);
|
||||
|
||||
/** Sundanese (Basa Sunda)
|
||||
* @author Irwangatot
|
||||
* @author Kandar
|
||||
*/
|
||||
$messages['su'] = array(
|
||||
'requestaccount-loginnotice' => "Pikeun miboga rekening pamaké, anjeun kudu '''[[Special:RequestAccount|daptar heula]]'''.",
|
||||
);
|
||||
|
||||
/** Swedish (svenska)
|
||||
* @author Boivie
|
||||
* @author Diupwijk
|
||||
* @author Fluff
|
||||
* @author Jon Harald Søby
|
||||
* @author Lejonel
|
||||
* @author M.M.S.
|
||||
* @author Najami
|
||||
* @author Per
|
||||
* @author WikiPhoenix
|
||||
*/
|
||||
$messages['sv'] = array(
|
||||
'confirmaccount-newrequests' => "'''$1''' öppnade e-post bekräftade att [[Special:ConfirmAccounts|{{PLURAL:$1|kontoansökning väntar på att behandlas|kontoansökningar väntar på att behandlas}}]]. '''Din uppmärksamhet krävs!'''",
|
||||
'requestaccount-loginnotice' => "För att få ett användarkonto måste du '''[[Special:RequestAccount|ansöka om det]]'''.",
|
||||
'right-confirmaccount' => 'Visa [[Special:ConfirmAccounts|kön av kontoansökningar]]',
|
||||
'right-requestips' => 'Visa sökandens IP-adress vid behandling av kontoansökningar',
|
||||
'right-lookupcredentials' => 'Visa [[Special:UserCredentials|användaruppgifter]]',
|
||||
);
|
||||
|
||||
/** Telugu (తెలుగు)
|
||||
* @author Chaduvari
|
||||
* @author Kiranmayee
|
||||
* @author Veeven
|
||||
* @author వైజాసత్య
|
||||
*/
|
||||
$messages['te'] = array(
|
||||
'confirmaccount-newrequests' => "ప్రస్తుతం '''$1''' {{PLURAL:$1|[[Special:ConfirmAccounts|ఖాతా అభ్యర్థన]]|[[Special:ConfirmAccounts|ఖాతా అభ్యర్థనలు]]}} వేచి{{PLURAL:$1|వుంది|వున్నాయి}}.", # Fuzzy
|
||||
'requestaccount-loginnotice' => "ఖాతా పొందడానికి, మీరు తప్పనిసరిగా '''[[Special:RequestAccount|అభ్యర్థించాలి]]'''.",
|
||||
);
|
||||
|
||||
/** Tajik (Cyrillic script) (тоҷикӣ)
|
||||
* @author Ibrahim
|
||||
*/
|
||||
$messages['tg-cyrl'] = array(
|
||||
'requestaccount-loginnotice' => "Барои дастрас кардани ҳисоби корбарӣ, шумо бояд '''[[Special:RequestAccount|дархост]]''' кунед.",
|
||||
);
|
||||
|
||||
/** Tajik (Latin script) (tojikī)
|
||||
* @author Liangent
|
||||
*/
|
||||
$messages['tg-latn'] = array(
|
||||
'requestaccount-loginnotice' => "Baroi dastras kardani hisobi korbarī, şumo bojad '''[[Special:RequestAccount|darxost]]''' kuned.",
|
||||
);
|
||||
|
||||
/** Thai (ไทย)
|
||||
* @author Ans
|
||||
* @author Harley Hartwell
|
||||
* @author Octahedron80
|
||||
* @author Passawuth
|
||||
*/
|
||||
$messages['th'] = array(
|
||||
'requestaccount-loginnotice' => "เพื่อที่จะได้มาซึ่งบัญชีผู้ใช้ใหม่ คุณต้อง'''[[Special:RequestAccount|ทำการขอบัญชีผู้ใช้]]'''",
|
||||
);
|
||||
|
||||
/** Tagalog (Tagalog)
|
||||
* @author AnakngAraw
|
||||
*/
|
||||
$messages['tl'] = array(
|
||||
'confirmaccount-newrequests' => "'''$1''' bukas na e-liham ang natiyak [[Special:ConfirmAccounts|ang akawnt na {{PLURAL:$1|hiniling ay nakabinbin|mga hiniling ay nakabinbin}}]]. '''Kailangan ang pagpansin mo!'''",
|
||||
'requestaccount-loginnotice' => "Upang makatanggap ng isang akawnt ng tagagamit, dapat kang '''[[Special:RequestAccount|humiling ng isa]]'''.",
|
||||
'right-confirmaccount' => 'Tingnan ang [[Special:ConfirmAccounts|pila na may hinihiling na mga akawnt]]',
|
||||
'right-requestips' => 'Tingnan ang mga adres ng IP ng humihiling habang isinasagawa ang hinihiling na mga akawnt',
|
||||
'right-lookupcredentials' => 'Tingnan ang [[Special:UserCredentials|mga kredensyal ng tagagamit]]',
|
||||
);
|
||||
|
||||
/** Turkish (Türkçe)
|
||||
* @author Homonihilis
|
||||
* @author Karduelis
|
||||
* @author Mach
|
||||
* @author Suelnur
|
||||
* @author Vito Genovese
|
||||
*/
|
||||
$messages['tr'] = array(
|
||||
'confirmaccount-newrequests' => "'''$1''' açık e-postası doğrulanmış [[Special:ConfirmAccounts|hesap {{PLURAL:$1|istek|istek}}]] beklemede", # Fuzzy
|
||||
'requestaccount-loginnotice' => "Bir kullanıcı hesabı almak için, '''[[Special:RequestAccount|istekte bulunmanız]]''' gerekmektedir.",
|
||||
'right-confirmaccount' => '[[Special:ConfirmAccounts|Hesap istekleri grubunu]] görür',
|
||||
'right-requestips' => 'İstenen hesaplarla ilgili işlem yaparken istek sahibinin IP adresini görür',
|
||||
'right-lookupcredentials' => '[[Special:UserCredentials|Kullanıcı referanslarını]] görür',
|
||||
);
|
||||
|
||||
/** Cantonese (粵語)
|
||||
*/
|
||||
$messages['yue'] = array(
|
||||
'requestaccount-loginnotice' => "要拎一個用戶戶口,你一定要'''[[Special:RequestAccount|請求一個]]'''。",
|
||||
);
|
||||
|
||||
/** Simplified Chinese (中文(简体))
|
||||
* @author Chenxiaoqino
|
||||
* @author Hydra
|
||||
* @author Kuailong
|
||||
* @author Mark85296341
|
||||
* @author Wilsonmess
|
||||
*/
|
||||
$messages['zh-hans'] = array(
|
||||
'requestaccount-loginnotice' => "要取得个用户账户,您一定要'''[[Special:RequestAccount|请求一个]]'''。",
|
||||
'right-confirmaccount' => '查看 [[Special:ConfirmAccounts|请求帐户的队列]]',
|
||||
'right-requestips' => '在处理请求的帐户查看请求者的 IP 地址',
|
||||
'right-lookupcredentials' => '查看 [[Special:UserCredentials|用户凭据]]',
|
||||
);
|
||||
|
||||
/** Traditional Chinese (中文(繁體))
|
||||
* @author Mark85296341
|
||||
* @author Waihorace
|
||||
*/
|
||||
$messages['zh-hant'] = array(
|
||||
'confirmaccount-newrequests' => "'''$1'''開啟電郵確認[[Special:ConfirmAccounts|{{PLURAL:$1|帳戶請求|多個帳戶請求}}]]待審中", # Fuzzy
|
||||
'requestaccount-loginnotice' => "要取得個使用者帳號,您一定要'''[[Special:RequestAccount|請求一個]]'''。",
|
||||
'right-confirmaccount' => '查看[[Special:ConfirmAccounts|待審帳戶隊列]]',
|
||||
'right-requestips' => '在處理帳戶請求時查看請求者的IP地址',
|
||||
'right-lookupcredentials' => '查看[[Special:UserCredentials|用戶憑據]]',
|
||||
);
|
8359
ConfirmAccount/frontend/language/ConfirmAccountPage.i18n.php
Normal file
8359
ConfirmAccount/frontend/language/ConfirmAccountPage.i18n.php
Normal file
File diff suppressed because it is too large
Load diff
4713
ConfirmAccount/frontend/language/RequestAccountPage.i18n.php
Normal file
4713
ConfirmAccount/frontend/language/RequestAccountPage.i18n.php
Normal file
File diff suppressed because it is too large
Load diff
2333
ConfirmAccount/frontend/language/UserCredentialsPage.i18n.php
Normal file
2333
ConfirmAccount/frontend/language/UserCredentialsPage.i18n.php
Normal file
File diff suppressed because it is too large
Load diff
23
ConfirmAccount/frontend/modules/confirmaccount.css
Normal file
23
ConfirmAccount/frontend/modules/confirmaccount.css
Normal file
|
@ -0,0 +1,23 @@
|
|||
/* RC pending account request notice */
|
||||
.mw-confirmaccount-bar {
|
||||
padding: 3px;
|
||||
margin: 5px;
|
||||
border: 1px solid #990000;
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.mw-confirmaccount-type-0 {
|
||||
background-color: #f0fff0;
|
||||
}
|
||||
|
||||
.mw-confirmaccount-body-0 {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.mw-confirmaccount-type-1 {
|
||||
background-color: #f0ffff;
|
||||
}
|
||||
|
||||
.mw-confirmaccount-body-1 {
|
||||
background-color: #f9f9f9;
|
||||
}
|
|
@ -0,0 +1,846 @@
|
|||
<?php
|
||||
|
||||
class ConfirmAccountsPage extends SpecialPage {
|
||||
protected $queueType = -1;
|
||||
protected $acrID = 0;
|
||||
protected $file = '';
|
||||
|
||||
protected $showHeld = false;
|
||||
protected $showRejects = false;
|
||||
protected $showStale = false;
|
||||
|
||||
/** @var UserAccountRequest */
|
||||
protected $accountReq;
|
||||
protected $reqUsername;
|
||||
protected $reqType;
|
||||
protected $reqBio;
|
||||
/** @var array */
|
||||
protected $reqAreas;
|
||||
|
||||
protected $submitType;
|
||||
protected $reason;
|
||||
|
||||
function __construct() {
|
||||
parent::__construct( 'ConfirmAccounts', 'confirmaccount' );
|
||||
}
|
||||
|
||||
function execute( $par ) {
|
||||
global $wgAccountRequestTypes;
|
||||
|
||||
$reqUser = $this->getUser();
|
||||
$request = $this->getRequest();
|
||||
|
||||
if ( !$reqUser->isAllowed( 'confirmaccount' ) ) {
|
||||
throw new PermissionsError( 'confirmaccount' );
|
||||
} elseif ( !$reqUser->getID() ) {
|
||||
throw new PermissionsError( 'user' );
|
||||
}
|
||||
|
||||
$this->setHeaders();
|
||||
|
||||
# Use the special page param to act as a super type.
|
||||
# Convert this to its integer form.
|
||||
$this->queueType = -1;
|
||||
foreach ( $wgAccountRequestTypes as $i => $params ) {
|
||||
if ( $params[0] === $par ) {
|
||||
$this->queueType = $i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
# User account request ID
|
||||
$this->acrID = $request->getIntOrNull( 'acrid' );
|
||||
# Attachment file name to view
|
||||
$this->file = $request->getVal( 'file' );
|
||||
|
||||
# Held requests hidden by default
|
||||
$this->showHeld = $request->getBool( 'wpShowHeld' );
|
||||
# Show stale requests
|
||||
$this->showStale = $request->getBool( 'wpShowStale' );
|
||||
# For viewing rejected requests (stale requests count as rejected)
|
||||
$this->showRejects = $request->getBool( 'wpShowRejects' );
|
||||
|
||||
// Showing a file
|
||||
if ( $this->file ) {
|
||||
$this->showFile( $this->file );
|
||||
return; // nothing else to do
|
||||
// Showing or confirming an account request
|
||||
} elseif ( $this->acrID ) {
|
||||
# Load areas user plans to be active in...
|
||||
$this->reqAreas = array();
|
||||
foreach ( ConfirmAccount::getUserAreaConfig() as $name => $conf ) {
|
||||
$formName = "wpArea-" . htmlspecialchars( str_replace( ' ', '_', $name ) );
|
||||
$this->reqAreas[$name] = $request->getInt( $formName, -1 );
|
||||
}
|
||||
# Load in the UserAccountRequest obj
|
||||
$this->loadAccountRequest( $this->acrID, $request->wasPosted() );
|
||||
if ( $request->wasPosted() ) {
|
||||
# For renaming to alot for collisions with other local requests
|
||||
# that were accepted and added to some global $wgAuth system first
|
||||
$this->reqUsername = trim( $request->getText( 'wpNewName' ) );
|
||||
# For changing the position recieved by requester
|
||||
$this->reqType = $request->getIntOrNull( 'wpType' );
|
||||
if ( !isset( $wgAccountRequestTypes[$this->reqType] ) ) {
|
||||
$this->reqType = null;
|
||||
}
|
||||
# For removing private info or such from bios
|
||||
$this->reqBio = $request->getText( 'wpNewBio' );
|
||||
# Action the admin is taking and why
|
||||
$this->submitType = $request->getVal( 'wpSubmitType' );
|
||||
$this->reason = $request->getText( 'wpReason' );
|
||||
# Check if this is a valid submission...
|
||||
$token = $request->getVal( 'wpEditToken' );
|
||||
if ( $reqUser->matchEditToken( $token, $this->acrID ) ) {
|
||||
$this->doAccountConfirmSubmit();
|
||||
} else {
|
||||
$this->showAccountConfirmForm( $this->msg( 'sessionfailure' )->escaped() );
|
||||
}
|
||||
} else {
|
||||
$this->showAccountConfirmForm();
|
||||
}
|
||||
// Showing all account requests in a queue
|
||||
} elseif ( $this->queueType != -1 ) {
|
||||
$this->showList();
|
||||
// Showing all account request queues
|
||||
} else {
|
||||
$this->showQueues();
|
||||
}
|
||||
|
||||
// Show what queue we are in and links to the others
|
||||
$this->addQueueSubtitleLinks();
|
||||
|
||||
$this->getOutput()->addModules( 'ext.confirmAccount' ); // CSS
|
||||
}
|
||||
|
||||
protected function addQueueSubtitleLinks() {
|
||||
$titleObj = $this->getFullTitle();
|
||||
|
||||
# Show other sub-queue links. Grey out the current one.
|
||||
# When viewing a request, show them all.
|
||||
if ( $this->acrID || $this->showStale || $this->showRejects || $this->showHeld ) {
|
||||
$listLink = Linker::linkKnown(
|
||||
$titleObj,
|
||||
$this->msg( 'confirmaccount-showopen' )->escaped() );
|
||||
} else {
|
||||
$listLink = $this->msg( 'confirmaccount-showopen' )->escaped();
|
||||
}
|
||||
if ( $this->acrID || !$this->showHeld ) {
|
||||
$listLink = $this->getLanguage()->pipeList( array(
|
||||
$listLink,
|
||||
Linker::makeKnownLinkObj(
|
||||
$titleObj,
|
||||
$this->msg( 'confirmaccount-showheld' )->escaped(),
|
||||
'wpShowHeld=1'
|
||||
)
|
||||
) );
|
||||
} else {
|
||||
$listLink = $this->getLanguage()->pipeList( array(
|
||||
$listLink,
|
||||
$this->msg( 'confirmaccount-showheld' )->escaped()
|
||||
) );
|
||||
}
|
||||
if ( $this->acrID || !$this->showRejects ) {
|
||||
$listLink = $this->getLanguage()->pipeList( array(
|
||||
$listLink,
|
||||
Linker::makeKnownLinkObj( $titleObj,
|
||||
$this->msg( 'confirmaccount-showrej' )->escaped(),
|
||||
'wpShowRejects=1'
|
||||
)
|
||||
) );
|
||||
} else {
|
||||
$listLink = $this->getLanguage()->pipeList( array(
|
||||
$listLink,
|
||||
$this->msg( 'confirmaccount-showrej' )->escaped()
|
||||
) );
|
||||
}
|
||||
if ( $this->acrID || !$this->showStale ) {
|
||||
$listLink = $this->getLanguage()->pipeList( array(
|
||||
$listLink,
|
||||
Linker::makeKnownLinkObj( $titleObj,
|
||||
$this->msg( 'confirmaccount-showexp' )->escaped(),
|
||||
'wpShowStale=1'
|
||||
)
|
||||
) );
|
||||
} else {
|
||||
$listLink = $this->getLanguage()->pipeList( array(
|
||||
$listLink,
|
||||
$this->msg( 'confirmaccount-showexp' )->escaped()
|
||||
) );
|
||||
}
|
||||
|
||||
# Say what queue we are in...
|
||||
if ( $this->queueType != -1 ) {
|
||||
$viewall = Linker::makeKnownLinkObj(
|
||||
$this->getTitle(), $this->msg( 'confirmaccount-all' )->escaped() );
|
||||
|
||||
$this->getOutput()->setSubtitle(
|
||||
"<strong>" . $this->msg( 'confirmaccount-type' )->escaped() . " <i>" .
|
||||
$this->msg( "confirmaccount-type-{$this->queueType}" )->escaped() .
|
||||
"</i></strong> [{$listLink}] <strong>{$viewall}</strong>" );
|
||||
}
|
||||
}
|
||||
|
||||
protected function showQueues() {
|
||||
global $wgAccountRequestTypes;
|
||||
|
||||
$out = $this->getOutput();
|
||||
|
||||
$out->addWikiMsg( 'confirmaccount-maintext' );
|
||||
$out->wrapWikiMsg( "<p><strong>$1</strong></p>", 'confirmaccount-types' );
|
||||
|
||||
# List each queue and some information about it...
|
||||
$out->addHTML( '<ul>' );
|
||||
foreach ( $wgAccountRequestTypes as $i => $params ) {
|
||||
$titleObj = SpecialPage::getTitleFor( 'ConfirmAccounts', $params[0] );
|
||||
$counts = ConfirmAccount::getOpenRequestCount( $i );
|
||||
|
||||
$open = '<b>';
|
||||
$open .= Linker::makeKnownLinkObj(
|
||||
$titleObj,
|
||||
$this->msg( 'confirmaccount-q-open' )->escaped(),
|
||||
'wpShowHeld=0'
|
||||
);
|
||||
$open .= '</b> [' . $counts['open'] . ']';
|
||||
|
||||
$held = Linker::makeKnownLinkObj(
|
||||
$titleObj,
|
||||
$this->msg( 'confirmaccount-q-held' )->escaped(),
|
||||
'wpShowHeld=1'
|
||||
);
|
||||
$held .= ' [' . $counts['held'] . ']';
|
||||
|
||||
$rejects = Linker::makeKnownLinkObj(
|
||||
$titleObj,
|
||||
$this->msg( 'confirmaccount-q-rej' )->escaped(),
|
||||
'wpShowRejects=1'
|
||||
);
|
||||
$rejects .= ' [' . $counts['rejected'] . ']';
|
||||
|
||||
$stale = '<i>';
|
||||
$stale .= Linker::makeKnownLinkObj(
|
||||
$titleObj,
|
||||
$this->msg( 'confirmaccount-q-stale' )->escaped(),
|
||||
'wpShowStale=1'
|
||||
);
|
||||
$stale .= '</i>';
|
||||
|
||||
$out->addHTML( "<li><i>" . $this->msg( "confirmaccount-type-$i" )->escaped() . "</i>" );
|
||||
$out->addHTML( $this->msg( 'word-separator' )->plain() );
|
||||
$params = $this->getLanguage()->pipeList( array( $open, $held, $rejects, $stale ) );
|
||||
$out->addHTML( $this->msg( 'parentheses' )->rawParams( $params )->escaped() );
|
||||
$out->addHTML( '</li>' );
|
||||
}
|
||||
|
||||
$out->addHTML( '</ul>' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $msg string
|
||||
*/
|
||||
protected function showAccountConfirmForm( $msg = '' ) {
|
||||
global $wgAccountRequestTypes;
|
||||
|
||||
$out = $this->getOutput();
|
||||
$reqUser = $this->getUser();
|
||||
$titleObj = $this->getFullTitle();
|
||||
|
||||
$accountReq = $this->accountReq; // convenience
|
||||
if ( !$accountReq || $accountReq->isDeleted() && !$this->showRejects ) {
|
||||
$out->addHTML( $this->msg( 'confirmaccount-badid' )->escaped() );
|
||||
$out->returnToMain( true, $titleObj );
|
||||
return;
|
||||
}
|
||||
|
||||
# Output any failure message
|
||||
if ( $msg != '' ) {
|
||||
$out->addHTML( '<div class="errorbox">' . $msg . '</div><div class="visualClear"></div>' );
|
||||
}
|
||||
|
||||
$out->addWikiMsg( 'confirmaccount-text' );
|
||||
|
||||
$rejectTimestamp = $accountReq->getRejectTimestamp();
|
||||
$heldTimestamp = $accountReq->getHeldTimestamp();
|
||||
$reason = strlen( $accountReq->getHandlingComment() )
|
||||
? htmlspecialchars( $accountReq->getHandlingComment() )
|
||||
: $this->msg( 'confirmaccount-noreason' )->escaped();
|
||||
$adminId = $accountReq->getHandlingUser();
|
||||
|
||||
if ( $rejectTimestamp ) {
|
||||
$datim = $this->getLanguage()->timeanddate( $rejectTimestamp, true );
|
||||
$date = $this->getLanguage()->date( $rejectTimestamp, true );
|
||||
$time = $this->getLanguage()->time( $rejectTimestamp, true );
|
||||
# Auto-rejected requests have a user ID of zero
|
||||
if ( $adminId ) {
|
||||
$out->addHTML( '<p><b>' . $this->msg( 'confirmaccount-reject',
|
||||
User::whoIs( $adminId ), $datim, $date, $time )->parse() . '</b></p>' );
|
||||
$out->addHTML( '<p><strong>' . $this->msg( 'confirmaccount-rational' )->escaped() . '</strong><i> ' .
|
||||
$reason . '</i></p>' );
|
||||
} else {
|
||||
$out->addHTML( "<p><i> $reason </i></p>" );
|
||||
}
|
||||
} elseif ( $heldTimestamp ) {
|
||||
$datim = $this->getLanguage()->timeanddate( $heldTimestamp, true );
|
||||
$date = $this->getLanguage()->date( $heldTimestamp, true );
|
||||
$time = $this->getLanguage()->time( $heldTimestamp, true );
|
||||
|
||||
$out->addHTML( '<p><b>' . $this->msg( 'confirmaccount-held',
|
||||
User::whoIs( $adminId ), $datim, $date, $time )->parse() . '</b></p>' );
|
||||
$out->addHTML( '<p><strong>' . $this->msg( 'confirmaccount-rational' )->escaped() . '</strong><i> ' .
|
||||
$reason . '</i></p>' );
|
||||
}
|
||||
|
||||
$form = Xml::openElement( 'form', array( 'method' => 'post', 'name' => 'accountconfirm',
|
||||
'action' => $titleObj->getLocalUrl() ) );
|
||||
|
||||
$form .= "<fieldset>";
|
||||
$form .= '<legend>' . $this->msg( 'confirmaccount-leg-user' )->escaped() . '</legend>';
|
||||
$form .= '<table cellpadding=\'4\'>';
|
||||
$form .= "<tr><td>" . Xml::label( $this->msg( 'username' )->text(), 'wpNewName' ) . "</td>";
|
||||
$form .= "<td>" . Xml::input( 'wpNewName', 30, $this->reqUsername, array( 'id' => 'wpNewName' ) ) . "</td></tr>\n";
|
||||
$econf = '';
|
||||
if ( $accountReq->getEmailAuthTimestamp() ) {
|
||||
$econf = ' <strong>' . $this->msg( 'confirmaccount-econf' )->escaped() . '</strong>';
|
||||
}
|
||||
$form .= "<tr><td>" . $this->msg( 'confirmaccount-email' )->escaped() . "</td>";
|
||||
$form .= "<td>" . htmlspecialchars( $accountReq->getEmail() ) . $econf . "</td></tr>\n";
|
||||
if ( count( $wgAccountRequestTypes ) > 1 ) {
|
||||
$options = array();
|
||||
$form .= "<tr><td><strong>" . $this->msg( 'confirmaccount-reqtype' )->escaped() . "</strong></td><td>";
|
||||
foreach ( $wgAccountRequestTypes as $i => $params ) {
|
||||
$options[] = Xml::option( $this->msg( "confirmaccount-pos-$i" )->text(), $i, ( $i == $this->reqType ) );
|
||||
}
|
||||
$form .= Xml::openElement( 'select', array( 'name' => "wpType" ) );
|
||||
$form .= implode( "\n", $options );
|
||||
$form .= Xml::closeElement( 'select' ) . "\n";
|
||||
$form .= "</td></tr>\n";
|
||||
}
|
||||
$form .= '</table></fieldset>';
|
||||
|
||||
$userAreas = ConfirmAccount::getUserAreaConfig();
|
||||
if ( $this->hasItem( 'AreasOfInterest' ) && count( $userAreas ) > 0 ) {
|
||||
$form .= '<fieldset>';
|
||||
$form .= '<legend>' . $this->msg( 'confirmaccount-leg-areas' )->escaped() . '</legend>';
|
||||
|
||||
$form .= "<div style='height:150px; overflow:scroll; background-color:#f9f9f9;'>";
|
||||
$form .= "<table cellspacing='5' cellpadding='0' style='background-color:#f9f9f9;'><tr valign='top'>";
|
||||
$count = 0;
|
||||
foreach ( $userAreas as $name => $conf ) {
|
||||
$count++;
|
||||
if ( $count > 5 ) {
|
||||
$form .= "</tr><tr valign='top'>";
|
||||
$count = 1;
|
||||
}
|
||||
$formName = "wpArea-" . htmlspecialchars( str_replace( ' ', '_', $name ) );
|
||||
if ( $conf['project'] != '' ) {
|
||||
$pg = Linker::linkKnown(
|
||||
Title::newFromText( $conf['project'] ),
|
||||
$this->msg( 'requestaccount-info' )->escaped()
|
||||
);
|
||||
} else {
|
||||
$pg = '';
|
||||
}
|
||||
$form .= "<td>" .
|
||||
Xml::checkLabel( $name, $formName, $formName, $this->reqAreas[$name] > 0 ) .
|
||||
" {$pg}</td>\n";
|
||||
}
|
||||
$form .= "</tr></table></div>";
|
||||
$form .= '</fieldset>';
|
||||
}
|
||||
|
||||
if ( $this->hasItem( 'Biography' ) || $this->hasItem( 'RealName' ) ) {
|
||||
$form .= '<fieldset>';
|
||||
$form .= '<legend>' . $this->msg( 'confirmaccount-leg-person' )->escaped() . '</legend>';
|
||||
if ( $this->hasItem( 'RealName' ) ) {
|
||||
$form .= '<table cellpadding=\'4\'>';
|
||||
$form .= "<tr><td>" . $this->msg( 'confirmaccount-real' )->escaped() . "</td>";
|
||||
$form .= "<td>" . htmlspecialchars( $accountReq->getRealName() ) . "</td></tr>\n";
|
||||
$form .= '</table>';
|
||||
}
|
||||
if ( $this->hasItem( 'Biography' ) ) {
|
||||
$form .= "<p>" . $this->msg( 'confirmaccount-bio' )->escaped() . "\n";
|
||||
$form .= "<textarea tabindex='1' name='wpNewBio' id='wpNewBio' rows='12' cols='80' style='width:100%; background-color:#f9f9f9;'>" .
|
||||
htmlspecialchars( $this->reqBio ) .
|
||||
"</textarea></p>\n";
|
||||
}
|
||||
$form .= '</fieldset>';
|
||||
}
|
||||
|
||||
if ( $this->hasItem( 'CV' ) || $this->hasItem( 'Notes' ) || $this->hasItem( 'Links' ) ) {
|
||||
$form .= '<fieldset>';
|
||||
$form .= '<legend>' . $this->msg( 'confirmaccount-leg-other' )->escaped() . '</legend>';
|
||||
if ( $this->hasItem( 'CV' ) ) {
|
||||
$form .= '<p>' . $this->msg( 'confirmaccount-attach' )->escaped() . ' ';
|
||||
if ( $accountReq->getFileName() !== null ) {
|
||||
$form .= Linker::makeKnownLinkObj( $titleObj,
|
||||
htmlspecialchars( $accountReq->getFileName() ),
|
||||
'file=' . $accountReq->getFileStorageKey() );
|
||||
} else {
|
||||
$form .= $this->msg( 'confirmaccount-none-p' )->escaped();
|
||||
}
|
||||
}
|
||||
if ( $this->hasItem( 'Notes' ) ) {
|
||||
$form .= "</p><p>" . $this->msg( 'confirmaccount-notes' )->escaped() . "\n";
|
||||
$form .= "<textarea tabindex='1' readonly='readonly' name='wpNotes' id='wpNotes' rows='3' cols='80' style='width:100%'>" .
|
||||
htmlspecialchars( $accountReq->getNotes() ) .
|
||||
"</textarea></p>\n";
|
||||
}
|
||||
if ( $this->hasItem( 'Links' ) ) {
|
||||
$form .= "<p>" . $this->msg( 'confirmaccount-urls' )->escaped() . "</p>\n";
|
||||
$form .= self::parseLinks( $accountReq->getUrls() );
|
||||
}
|
||||
$form .= '</fieldset>';
|
||||
}
|
||||
|
||||
if ( $reqUser->isAllowed( 'requestips' ) ) {
|
||||
$blokip = SpecialPage::getTitleFor( 'Block' );
|
||||
$link = Linker::makeKnownLinkObj(
|
||||
$blokip,
|
||||
$this->msg( 'blockip' )->escaped(),
|
||||
'ip=' . $accountReq->getIP() . '&wpCreateAccount=1'
|
||||
);
|
||||
$form .= '<fieldset>';
|
||||
$form .= '<legend>' . $this->msg( 'confirmaccount-leg-ip' )->escaped() . '</legend>';
|
||||
$wordSeparator = $this->msg( 'word-separator' )->plain();
|
||||
$form .= "<p>";
|
||||
// @todo FIXME: Bad i18n. Should probably be something like
|
||||
// "confirmaccount-ip $1 ($2)" to get rid of this mess.
|
||||
$form .= $this->msg( 'confirmaccount-ip' )->escaped();
|
||||
$form .= $wordSeparator;
|
||||
$form .= htmlspecialchars( $accountReq->getIP() );
|
||||
$form .= $wordSeparator;
|
||||
$form .= $this->msg( 'parentheses' )->rawParams( $link )->escaped();
|
||||
$form .= "</p>\n";
|
||||
if ( $accountReq->getXFF() ) {
|
||||
$form .= "<p>" . $this->msg( 'confirmaccount-xff' )->escaped() .
|
||||
$wordSeparator . htmlspecialchars( $accountReq->getXFF() ) . "</p>\n";
|
||||
}
|
||||
if ( $accountReq->getAgent() ) {
|
||||
$form .= "<p>" . $this->msg( 'confirmaccount-agent' )->escaped() .
|
||||
$wordSeparator . htmlspecialchars( $accountReq->getAgent() ) . "</p>\n";
|
||||
}
|
||||
$form .= '</fieldset>';
|
||||
}
|
||||
|
||||
$form .= '<fieldset>';
|
||||
$form .= '<legend>' . $this->msg( 'confirmaccount-legend' )->escaped() . '</legend>';
|
||||
$form .= "<strong>" . $this->msg( 'confirmaccount-confirm' )->parse() . "</strong>\n";
|
||||
$form .= "<table cellpadding='5'><tr>";
|
||||
$form .= "<td>" . Xml::radio( 'wpSubmitType', 'accept', $this->submitType == 'accept',
|
||||
array( 'id' => 'submitCreate', 'onclick' => 'document.getElementById("wpComment").style.display="block"' ) );
|
||||
$form .= ' ' . Xml::label( $this->msg( 'confirmaccount-create' )->text(), 'submitCreate' ) . "</td>\n";
|
||||
$form .= "<td>" . Xml::radio( 'wpSubmitType', 'reject', $this->submitType == 'reject',
|
||||
array( 'id' => 'submitDeny', 'onclick' => 'document.getElementById("wpComment").style.display="block"' ) );
|
||||
$form .= ' ' . Xml::label( $this->msg( 'confirmaccount-deny' )->text(), 'submitDeny' ) . "</td>\n";
|
||||
$form .= "<td>" . Xml::radio( 'wpSubmitType', 'hold', $this->submitType == 'hold',
|
||||
array( 'id' => 'submitHold', 'onclick' => 'document.getElementById("wpComment").style.display="block"' ) );
|
||||
$form .= ' ' . Xml::label( $this->msg( 'confirmaccount-hold' )->text(), 'submitHold' ) . "</td>\n";
|
||||
$form .= "<td>" . Xml::radio( 'wpSubmitType', 'spam', $this->submitType == 'spam',
|
||||
array( 'id' => 'submitSpam', 'onclick' => 'document.getElementById("wpComment").style.display="none"' ) );
|
||||
$form .= ' ' . Xml::label( $this->msg( 'confirmaccount-spam' )->text(), 'submitSpam' ) . "</td>\n";
|
||||
$form .= "</tr></table>";
|
||||
$form .= "<div id='wpComment'><p>" . $this->msg( 'confirmaccount-reason' )->escaped() . "</p>\n";
|
||||
$form .= "<p><textarea name='wpReason' id='wpReason' rows='3' cols='80' style='width:80%; display=block;'>" .
|
||||
htmlspecialchars( $this->reason ) . "</textarea></p></div>\n";
|
||||
$form .= "<p>" . Xml::submitButton( $this->msg( 'confirmaccount-submit' )->text() ) . "</p>\n";
|
||||
$form .= '</fieldset>';
|
||||
|
||||
$form .= Html::Hidden( 'title', $titleObj->getPrefixedDBKey() ) . "\n";
|
||||
$form .= Html::Hidden( 'action', 'reject' );
|
||||
$form .= Html::Hidden( 'acrid', $accountReq->getId() );
|
||||
$form .= Html::Hidden( 'wpShowRejects', $this->showRejects );
|
||||
$form .= Html::Hidden( 'wpEditToken', $reqUser->getEditToken( $accountReq->getId() ) ) . "\n";
|
||||
$form .= Xml::closeElement( 'form' );
|
||||
|
||||
$out->addHTML( $form );
|
||||
|
||||
global $wgMemc;
|
||||
# Set a key to who is looking at this request.
|
||||
# Have it expire in 10 minutes...
|
||||
$key = wfMemcKey( 'acctrequest', 'view', $accountReq->getId() );
|
||||
$wgMemc->set( $key, $reqUser->getID(), 60 * 10 );
|
||||
}
|
||||
|
||||
protected function hasItem( $name ) {
|
||||
global $wgConfirmAccountRequestFormItems;
|
||||
|
||||
return $wgConfirmAccountRequestFormItems[$name]['enabled'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a private file requested by the visitor.
|
||||
* @param $key string
|
||||
*/
|
||||
protected function showFile( $key ) {
|
||||
global $wgConfirmAccountFSRepos;
|
||||
|
||||
$out = $this->getOutput();
|
||||
$request = $this->getRequest();
|
||||
|
||||
$out->disable();
|
||||
|
||||
# We mustn't allow the output to be Squid cached, otherwise
|
||||
# if an admin previews a private image, and it's cached, then
|
||||
# a user without appropriate permissions can toddle off and
|
||||
# nab the image, and Squid will serve it
|
||||
$request->response()->header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', 0 ) . ' GMT' );
|
||||
$request->response()->header( 'Cache-Control: no-cache, no-store, max-age=0, must-revalidate' );
|
||||
$request->response()->header( 'Pragma: no-cache' );
|
||||
|
||||
$repo = new FSRepo( $wgConfirmAccountFSRepos['accountreqs'] );
|
||||
$path = $repo->getZonePath( 'public' ) . '/' .
|
||||
UserAccountRequest::relPathFromKey( $key );
|
||||
|
||||
$repo->streamFile( $path );
|
||||
}
|
||||
|
||||
protected function doAccountConfirmSubmit() {
|
||||
if ( !$this->accountReq ) {
|
||||
$this->showAccountConfirmForm( $this->msg( 'confirmaccount-badid' )->escaped() );
|
||||
return;
|
||||
}
|
||||
|
||||
# Build submission object...
|
||||
$areaSet = array(); // make a simple list of interests
|
||||
foreach ( $this->reqAreas as $area => $val ) {
|
||||
if ( $val > 0 ) {
|
||||
$areaSet[] = $area;
|
||||
}
|
||||
}
|
||||
$submission = new AccountConfirmSubmission(
|
||||
$this->getUser(),
|
||||
$this->accountReq,
|
||||
array(
|
||||
'userName' => $this->reqUsername,
|
||||
'bio' => $this->reqBio,
|
||||
'type' => $this->reqType,
|
||||
'areas' => $areaSet,
|
||||
'action' => $this->submitType,
|
||||
'reason' => $this->reason
|
||||
)
|
||||
);
|
||||
|
||||
# Actually submit!
|
||||
list( $status, $msg ) = $submission->submit( $this->getContext() );
|
||||
|
||||
# Check for error messages
|
||||
if ( $status !== true ) {
|
||||
$this->showAccountConfirmForm( $msg );
|
||||
return;
|
||||
}
|
||||
|
||||
# Done!
|
||||
$this->showSuccess( $this->submitType, $this->reqUsername, (array)$msg );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get requested account request row and load some fields
|
||||
* @param $id int
|
||||
* @param $wasPosted bool
|
||||
* @return void
|
||||
*/
|
||||
protected function loadAccountRequest( $id, $wasPosted ) {
|
||||
$from = $wasPosted ? 'dbmaster' : 'dbslave';
|
||||
$this->accountReq = UserAccountRequest::newFromId( $id, $from );
|
||||
# Check if parameters are to be overridden
|
||||
if ( $this->accountReq ) {
|
||||
$this->reqUsername = ( $this->reqUsername != '' )
|
||||
? $this->reqUsername // overriden by admin
|
||||
: $this->accountReq->getName();
|
||||
$this->reqBio = ( $this->reqBio != '' )
|
||||
? $this->reqBio // overriden by admin
|
||||
: $this->accountReq->getBio();
|
||||
$this->reqType = !is_null( $this->reqType )
|
||||
? $this->reqType // overriden by admin
|
||||
: $this->accountReq->getType();
|
||||
|
||||
$origAreas = $this->accountReq->getAreas();
|
||||
foreach ( $this->reqAreas as $area => $within ) {
|
||||
# If admin didn't set any of these checks, go back to how the user set them.
|
||||
# On GET requests, the admin probably didn't set anything.
|
||||
if ( $within == -1 ) {
|
||||
if ( in_array( $area, $origAreas ) ) {
|
||||
$this->reqAreas[$area] = 1;
|
||||
} else {
|
||||
$this->reqAreas[$area] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a list of all recognized HTTP links in the text.
|
||||
* @param string $text
|
||||
* @return string $linkList, list of clickable links
|
||||
*/
|
||||
public static function parseLinks( $text ) {
|
||||
# Don't let this get flooded
|
||||
$max = 10;
|
||||
$count = 0;
|
||||
|
||||
$linkList = '';
|
||||
# Normalize space characters
|
||||
$text = str_replace( array( "\r", "\t" ), array( "\n", " " ), htmlspecialchars( $text ) );
|
||||
# Split out each line as a link
|
||||
$lines = explode( "\n", $text );
|
||||
foreach ( $lines as $line ) {
|
||||
$links = explode( " ", $line, 2 );
|
||||
$link = $links[0];
|
||||
# Any explanation text is not part of the link...
|
||||
$extra = isset( $links[1] ) ? ' ' . $links[1] : '';
|
||||
if ( strpos( $link, '.' ) ) {
|
||||
// @FIXME: other protocals
|
||||
$link = ( strpos( $link, 'http://' ) === false ) ? 'http://' . $link : $link;
|
||||
$linkList .= "<li><a href='$link'>$link</a>$extra</li>\n";
|
||||
}
|
||||
$count++;
|
||||
if ( $count >= $max )
|
||||
break;
|
||||
}
|
||||
if ( $linkList == '' ) {
|
||||
$linkList = wfMessage( 'confirmaccount-none-p' )->escaped();
|
||||
} else {
|
||||
$linkList = "<ul>{$linkList}</ul>";
|
||||
}
|
||||
return $linkList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $submitType string
|
||||
* @param $name string User name
|
||||
* @param $errors array
|
||||
*/
|
||||
protected function showSuccess( $submitType, $name = null, $errors = array() ) {
|
||||
$out = $this->getOutput();
|
||||
|
||||
$out->setPagetitle( $this->msg( 'actioncomplete' )->escaped() );
|
||||
if ( $this->submitType == 'accept' ) {
|
||||
$out->addWikiMsg( 'confirmaccount-acc', $name );
|
||||
} elseif ( $this->submitType == 'reject' || $this->submitType == 'spam' ) {
|
||||
$out->addWikiMsg( 'confirmaccount-rej' );
|
||||
} else {
|
||||
$out->redirect( $this->getFullTitle()->getFullUrl() );
|
||||
return;
|
||||
}
|
||||
# Output any errors
|
||||
foreach ( $errors as $error ) {
|
||||
$out->addHTML( '<p>' . $error . '</p>' );
|
||||
}
|
||||
# Give link to see other requests
|
||||
$out->returnToMain( true, $this->getFullTitle() );
|
||||
}
|
||||
|
||||
protected function showList() {
|
||||
$out = $this->getOutput();
|
||||
|
||||
# Output the list
|
||||
$pager = new ConfirmAccountsPager( $this, array(),
|
||||
$this->queueType, $this->showRejects, $this->showHeld, $this->showStale );
|
||||
|
||||
if ( $pager->getNumRows() ) {
|
||||
if ( $this->showStale ) {
|
||||
$out->addWikiMsg( 'confirmaccount-list3' );
|
||||
} elseif ( $this->showRejects ) {
|
||||
$out->addWikiMsg( 'confirmaccount-list2' );
|
||||
} else {
|
||||
$out->addWikiMsg( 'confirmaccount-list' );
|
||||
}
|
||||
$out->addHTML( $pager->getNavigationBar() );
|
||||
$out->addHTML( $pager->getBody() );
|
||||
$out->addHTML( $pager->getNavigationBar() );
|
||||
} else {
|
||||
if ( $this->showRejects ) {
|
||||
$out->addWikiMsg( 'confirmaccount-none-r' );
|
||||
} elseif ( $this->showStale ) {
|
||||
$out->addWikiMsg( 'confirmaccount-none-e' );
|
||||
} elseif ( $this->showHeld ) {
|
||||
$out->addWikiMsg( 'confirmaccount-none-h' );
|
||||
} else {
|
||||
$out->addWikiMsg( 'confirmaccount-none-o' );
|
||||
}
|
||||
}
|
||||
|
||||
# Every 30th view, prune old deleted items
|
||||
if ( 0 == mt_rand( 0, 29 ) ) {
|
||||
ConfirmAccount::runAutoMaintenance();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $row
|
||||
* @return string
|
||||
*/
|
||||
public function formatRow( $row ) {
|
||||
global $wgMemc;
|
||||
|
||||
if ( $this->showRejects || $this->showStale ) {
|
||||
$link = Linker::makeKnownLinkObj(
|
||||
$this->getFullTitle(),
|
||||
$this->msg( 'confirmaccount-review' )->escaped(),
|
||||
'acrid=' . (int)$row->acr_id . '&wpShowRejects=1' );
|
||||
} else {
|
||||
$link = Linker::makeKnownLinkObj(
|
||||
$this->getFullTitle(),
|
||||
$this->msg( 'confirmaccount-review' )->escaped(),
|
||||
'acrid=' . (int)$row->acr_id );
|
||||
}
|
||||
$time = $this->getLanguage()->timeanddate( wfTimestamp( TS_MW, $row->acr_registration ), true );
|
||||
|
||||
$r = "<li class='mw-confirmaccount-type-{$this->queueType}'>";
|
||||
|
||||
$r .= $time . " (<strong>{$link}</strong>)";
|
||||
# Auto-rejected accounts have a user ID of zero
|
||||
if ( $row->acr_rejected && $row->acr_user ) {
|
||||
$datim = $this->getLanguage()->timeanddate( wfTimestamp( TS_MW, $row->acr_rejected ), true );
|
||||
$date = $this->getLanguage()->date( wfTimestamp( TS_MW, $row->acr_rejected ), true );
|
||||
$time = $this->getLanguage()->time( wfTimestamp( TS_MW, $row->acr_rejected ), true );
|
||||
$r .= ' <b>' . $this->msg( 'confirmaccount-reject', $row->user_name, $datim, $date, $time )->parse() . '</b>';
|
||||
} elseif ( $row->acr_held && !$row->acr_rejected ) {
|
||||
$datim = $this->getLanguage()->timeanddate( wfTimestamp( TS_MW, $row->acr_held ), true );
|
||||
$date = $this->getLanguage()->date( wfTimestamp( TS_MW, $row->acr_held ), true );
|
||||
$time = $this->getLanguage()->time( wfTimestamp( TS_MW, $row->acr_held ), true );
|
||||
$r .= ' <b>' . $this->msg( 'confirmaccount-held', User::whoIs( $row->acr_user ), $datim, $date, $time )->parse() . '</b>';
|
||||
}
|
||||
# Check if someone is viewing this request
|
||||
$key = wfMemcKey( 'acctrequest', 'view', $row->acr_id );
|
||||
$value = $wgMemc->get( $key );
|
||||
if ( $value ) {
|
||||
$r .= ' <b>' . $this->msg( 'confirmaccount-viewing', User::whoIs( $value ) )->parse() . '</b>';
|
||||
}
|
||||
|
||||
$r .= "<br /><table class='mw-confirmaccount-body-{$this->queueType}' cellspacing='1' cellpadding='3' border='1' width='100%'>";
|
||||
if ( $this->hasItem( 'UserName' ) ) {
|
||||
$r .= '<tr><td><strong>' . $this->msg( 'confirmaccount-name' )->escaped() . '</strong></td><td width=\'100%\'>' .
|
||||
htmlspecialchars( $row->acr_name ) . '</td></tr>';
|
||||
}
|
||||
if ( $this->hasItem( 'RealName' ) ) {
|
||||
$hasCV = $row->acr_filename
|
||||
? ' <strong>' . $this->msg( 'confirmaccount-withcv' )->escaped() . '</strong>'
|
||||
: '';
|
||||
$r .= '<tr><td><strong>' . $this->msg( 'confirmaccount-real-q' )->escaped() . '</strong></td><td width=\'100%\'>' .
|
||||
htmlspecialchars( $row->acr_real_name ) . $hasCV . '</td></tr>';
|
||||
}
|
||||
$econf = $row->acr_email_authenticated
|
||||
? ' <strong>' . $this->msg( 'confirmaccount-econf' )->escaped() . '</strong>'
|
||||
: '';
|
||||
$r .= '<tr><td><strong>' . $this->msg( 'confirmaccount-email-q' )->escaped() . '</strong></td><td width=\'100%\'>' .
|
||||
htmlspecialchars( $row->acr_email ) . $econf . '</td></tr>';
|
||||
# Truncate this, blah blah...
|
||||
$bio = htmlspecialchars( $row->acr_bio );
|
||||
$preview = $this->getLanguage()->truncate( $bio, 400, '' );
|
||||
if ( strlen( $preview ) < strlen( $bio ) ) {
|
||||
$preview = substr( $preview, 0, strrpos( $preview, ' ' ) );
|
||||
$preview .= " . . .";
|
||||
}
|
||||
$r .= '<tr><td><strong>' . $this->msg( 'confirmaccount-bio-q' )->escaped() .
|
||||
'</strong></td><td width=\'100%\'><i>' . $preview . '</i></td></tr>';
|
||||
$r .= '</table>';
|
||||
|
||||
$r .= '</li>';
|
||||
|
||||
return $r;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Query to list out pending accounts
|
||||
*/
|
||||
class ConfirmAccountsPager extends ReverseChronologicalPager {
|
||||
public $mForm, $mConds;
|
||||
|
||||
function __construct(
|
||||
$form, $conds, $type, $rejects = false, $showHeld = false, $showStale = false
|
||||
) {
|
||||
$this->mForm = $form;
|
||||
$this->mConds = $conds;
|
||||
|
||||
$this->mConds['acr_type'] = $type;
|
||||
|
||||
$this->rejects = $rejects;
|
||||
$this->stale = $showStale;
|
||||
if ( $rejects || $showStale ) {
|
||||
$this->mConds['acr_deleted'] = 1;
|
||||
} else {
|
||||
$this->mConds['acr_deleted'] = 0;
|
||||
if ( $showHeld ) {
|
||||
$this->mConds[] = 'acr_held IS NOT NULL';
|
||||
} else {
|
||||
$this->mConds[] = 'acr_held IS NULL';
|
||||
}
|
||||
|
||||
}
|
||||
parent::__construct();
|
||||
# Treat 20 as the default limit, since each entry takes up 5 rows.
|
||||
$urlLimit = $this->mRequest->getInt( 'limit' );
|
||||
$this->mLimit = $urlLimit ? $urlLimit : 20;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Title
|
||||
*/
|
||||
function getTitle() {
|
||||
return $this->mForm->getFullTitle();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $row
|
||||
* @return string
|
||||
*/
|
||||
function formatRow( $row ) {
|
||||
return $this->mForm->formatRow( $row );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function getStartBody() {
|
||||
if ( $this->getNumRows() ) {
|
||||
return '<ul>';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function getEndBody() {
|
||||
if ( $this->getNumRows() ) {
|
||||
return '</ul>';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
function getQueryInfo() {
|
||||
$conds = $this->mConds;
|
||||
$tables = array( 'account_requests' );
|
||||
$fields = array( 'acr_id', 'acr_name', 'acr_real_name', 'acr_registration', 'acr_held',
|
||||
'acr_user', 'acr_email', 'acr_email_authenticated', 'acr_bio', 'acr_notes',
|
||||
'acr_urls', 'acr_filename', 'acr_type', 'acr_rejected' );
|
||||
# Stale requests have a user ID of zero
|
||||
if ( $this->stale ) {
|
||||
$conds[] = 'acr_user = 0';
|
||||
} elseif ( $this->rejects ) {
|
||||
$conds[] = 'acr_user != 0';
|
||||
$tables[] = 'user';
|
||||
$conds[] = 'acr_user = user_id';
|
||||
$fields[] = 'user_name';
|
||||
$fields[] = 'acr_rejected';
|
||||
}
|
||||
return array(
|
||||
'tables' => $tables,
|
||||
'fields' => $fields,
|
||||
'conds' => $conds
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function getIndexField() {
|
||||
return 'acr_registration';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,397 @@
|
|||
<?php
|
||||
|
||||
class RequestAccountPage extends SpecialPage {
|
||||
protected $mUsername; // string
|
||||
protected $mRealName; // string
|
||||
protected $mEmail; // string
|
||||
protected $mBio; // string
|
||||
protected $mNotes; // string
|
||||
protected $mUrls; // string
|
||||
protected $mToS; // bool
|
||||
protected $mType; // integer
|
||||
/** @var Array */
|
||||
protected $mAreas;
|
||||
|
||||
protected $mPrevAttachment; // string
|
||||
protected $mForgotAttachment; // bool
|
||||
protected $mSrcName; // string
|
||||
protected $mFileSize; // integer
|
||||
protected $mTempPath; // string
|
||||
|
||||
function __construct() {
|
||||
parent::__construct( 'RequestAccount' );
|
||||
}
|
||||
|
||||
function execute( $par ) {
|
||||
global $wgAccountRequestTypes;
|
||||
|
||||
$reqUser = $this->getUser();
|
||||
$request = $this->getRequest();
|
||||
|
||||
$block = ConfirmAccount::getAccountRequestBlock( $reqUser );
|
||||
if ( $block ) {
|
||||
throw new UserBlockedError( $block );
|
||||
} elseif ( wfReadOnly() ) {
|
||||
throw new ReadOnlyError();
|
||||
}
|
||||
|
||||
|
||||
|
||||
$this->setHeaders();
|
||||
|
||||
//$this->mRealName = trim( $request->getText( 'wpRealName' ) );
|
||||
# We may only want real names being used
|
||||
$this->mUsername = !$this->hasItem( 'UserName' )
|
||||
? $this->mRealName
|
||||
: $request->getText( 'wpUsername' );
|
||||
$this->mUsername = trim( $this->mUsername );
|
||||
# CV/resume attachment...
|
||||
if ( $this->hasItem( 'CV' ) ) {
|
||||
$this->initializeUpload( $request );
|
||||
$this->mPrevAttachment = $request->getText( 'attachment' );
|
||||
$this->mForgotAttachment = $request->getBool( 'forgotAttachment' );
|
||||
}
|
||||
# Other identifying fields...
|
||||
$this->mEmail = trim( $request->getText( 'wpEmail' ) );
|
||||
//$this->mBio = $this->hasItem( 'Biography' ) ? $request->getText( 'wpBio', '' ) : '';
|
||||
$this->mNotes = $this->hasItem( 'Notes' ) ? $request->getText( 'wpNotes', '' ) : '';
|
||||
//$this->mUrls = $this->hasItem( 'Links' ) ? $request->getText( 'wpUrls', '' ) : '';
|
||||
# Site terms of service...
|
||||
$this->mToS = $this->hasItem( 'TermsOfService' ) ? $request->getBool( 'wpToS' ) : false;
|
||||
# Which account request queue this belongs in...
|
||||
$this->mType = $request->getInt( 'wpType' );
|
||||
$this->mType = isset( $wgAccountRequestTypes[$this->mType] ) ? $this->mType : 0;
|
||||
# Load areas user plans to be active in...
|
||||
$this->mAreas = array();
|
||||
if ( $this->hasItem( 'AreasOfInterest' ) ) {
|
||||
foreach ( ConfirmAccount::getUserAreaConfig() as $name => $conf ) {
|
||||
$formName = "wpArea-" . htmlspecialchars( str_replace( ' ', '_', $name ) );
|
||||
$this->mAreas[$name] = $request->getInt( $formName, -1 );
|
||||
}
|
||||
}
|
||||
# We may be confirming an email address here
|
||||
$emailCode = $request->getText( 'wpEmailToken' );
|
||||
|
||||
$action = $request->getVal( 'action' );
|
||||
if ( $request->wasPosted()
|
||||
&& $reqUser->matchEditToken( $request->getVal( 'wpEditToken' ) ) )
|
||||
{
|
||||
$this->mPrevAttachment = $this->mPrevAttachment
|
||||
? $this->mPrevAttachment
|
||||
: $this->mSrcName;
|
||||
$this->doSubmit();
|
||||
} elseif ( $action == 'confirmemail' ) {
|
||||
$this->confirmEmailToken( $emailCode );
|
||||
} else {
|
||||
$this->showForm();
|
||||
}
|
||||
|
||||
$this->getOutput()->addModules( 'ext.confirmAccount' ); // CSS
|
||||
}
|
||||
|
||||
protected function showForm( $msg = '', $forgotFile = 0 ) {
|
||||
global $wgAccountRequestTypes, $wgMakeUserPageFromBio;
|
||||
|
||||
$reqUser = $this->getUser();
|
||||
|
||||
$this->mForgotAttachment = $forgotFile;
|
||||
|
||||
$out = $this->getOutput();
|
||||
$out->setPagetitle( $this->msg( "requestaccount" )->escaped() );
|
||||
# Output failure message if any
|
||||
if ( $msg ) {
|
||||
$out->addHTML( '<div class="errorbox">' . $msg . '</div><div class="visualClear"></div>' );
|
||||
}
|
||||
# Give notice to users that are logged in
|
||||
if ( $reqUser->getID() ) {
|
||||
$out->addWikiMsg( 'requestaccount-dup' );
|
||||
}
|
||||
|
||||
$out->addWikiMsg( 'requestaccount-text' );
|
||||
|
||||
$form = Xml::openElement( 'form', array( 'method' => 'post', 'name' => 'accountrequest',
|
||||
'action' => $this->getTitle()->getLocalUrl(), 'enctype' => 'multipart/form-data' ) );
|
||||
|
||||
$form .= '<fieldset><legend>' . $this->msg( 'requestaccount-leg-user' )->escaped() . '</legend>';
|
||||
$form .= $this->msg( 'requestaccount-acc-text' )->parseAsBlock() . "\n";
|
||||
$form .= '<table cellpadding=\'4\'>';
|
||||
if ( $this->hasItem( 'UserName' ) ) {
|
||||
$form .= "<tr><td>" . Xml::label( $this->msg( 'username' )->text(), 'wpUsername' ) . "</td>";
|
||||
$form .= "<td>" . Xml::input( 'wpUsername', 30, $this->mUsername, array( 'id' => 'wpUsername' ) ) . "</td></tr>\n";
|
||||
} else {
|
||||
$form .= "<tr><td>" . $this->msg( 'username' )->escaped() . "</td>";
|
||||
$form .= "<td>" . $this->msg( 'requestaccount-same' )->escaped() . "</td></tr>\n";
|
||||
}
|
||||
//$form .= "<tr><td>" . Xml::label( $this->msg( 'requestaccount-email' )->text(), 'wpEmail' ) . "</td>";
|
||||
//$form .= "<td>" . Xml::input( 'wpEmail', 30, $this->mEmail, array( 'id' => 'wpEmail' ) ) . "</td></tr>\n";
|
||||
if ( count( $wgAccountRequestTypes ) > 1 ) {
|
||||
$form .= "<tr><td>" . $this->msg( 'requestaccount-reqtype' )->escaped() . "</td><td>";
|
||||
$options = array();
|
||||
foreach ( $wgAccountRequestTypes as $i => $params ) {
|
||||
$options[] = Xml::option( $this->msg( "requestaccount-level-$i" )->text(), $i, ( $i == $this->mType ) );
|
||||
}
|
||||
$form .= Xml::openElement( 'select', array( 'name' => "wpType" ) );
|
||||
$form .= implode( "\n", $options );
|
||||
$form .= Xml::closeElement( 'select' ) . "\n";
|
||||
$form .= '</td></tr>';
|
||||
}
|
||||
$form .= '</table></fieldset>';
|
||||
|
||||
$userAreas = ConfirmAccount::getUserAreaConfig();
|
||||
if ( $this->hasItem( 'AreasOfInterest' ) && count( $userAreas ) > 0 ) {
|
||||
$form .= '<fieldset>';
|
||||
$form .= '<legend>' . $this->msg( 'requestaccount-leg-areas' )->escaped() . '</legend>';
|
||||
$form .= $this->msg( 'requestaccount-areas-text' )->parseAsBlock() . "\n";
|
||||
|
||||
$form .= "<div style='height:150px; overflow:scroll; background-color:#f9f9f9;'>";
|
||||
$form .= "<table cellspacing='5' cellpadding='0' style='background-color:#f9f9f9;'><tr valign='top'>";
|
||||
$count = 0;
|
||||
foreach ( $userAreas as $name => $conf ) {
|
||||
$count++;
|
||||
if ( $count > 5 ) {
|
||||
$form .= "</tr><tr valign='top'>";
|
||||
$count = 1;
|
||||
}
|
||||
$formName = "wpArea-" . htmlspecialchars( str_replace( ' ', '_', $name ) );
|
||||
if ( $conf['project'] != '' ) {
|
||||
$pg = Linker::link( Title::newFromText( $conf['project'] ),
|
||||
$this->msg( 'requestaccount-info' )->escaped(), array(), array(), "known" );
|
||||
} else {
|
||||
$pg = '';
|
||||
}
|
||||
$form .= "<td>" .
|
||||
Xml::checkLabel( $name, $formName, $formName, $this->mAreas[$name] > 0 ) .
|
||||
" {$pg}</td>\n";
|
||||
}
|
||||
$form .= "</tr></table></div>";
|
||||
$form .= '</fieldset>';
|
||||
}
|
||||
|
||||
/*if ( $this->hasItem( 'Biography' ) || $this->hasItem( 'RealName' ) ) {
|
||||
$form .= '<fieldset>';
|
||||
$form .= '<legend>' . $this->msg( 'requestaccount-leg-person' )->escaped() . '</legend>';
|
||||
if ( $this->hasItem( 'RealName' ) ) {
|
||||
$form .= '<table cellpadding=\'4\'>';
|
||||
$form .= "<tr><td>" . Xml::label( $this->msg( 'requestaccount-real' )->text(), 'wpRealName' ) . "</td>";
|
||||
$form .= "<td>" . Xml::input( 'wpRealName', 35, $this->mRealName, array( 'id' => 'wpRealName' ) ) . "</td></tr>\n";
|
||||
$form .= '</table>';
|
||||
}
|
||||
if ( $this->hasItem( 'Biography' ) ) {
|
||||
if ( $wgMakeUserPageFromBio ) {
|
||||
$form .= $this->msg( 'requestaccount-bio-text-i' )->parseAsBlock() . "\n";
|
||||
}
|
||||
$form .= $this->msg( 'requestaccount-bio-text' )->parseAsBlock() . "\n";
|
||||
$form .= "<p>" . $this->msg( 'requestaccount-bio' )->parse() . "\n";
|
||||
$form .= "<textarea tabindex='1' name='wpBio' id='wpBio' rows='12' cols='80' style='width:100%; background-color:#f9f9f9;'>" .
|
||||
htmlspecialchars( $this->mBio ) . "</textarea></p>\n";
|
||||
}
|
||||
$form .= '</fieldset>';
|
||||
}*/
|
||||
|
||||
if ( $this->hasItem( 'CV' ) || $this->hasItem( 'Notes' ) || $this->hasItem( 'Links' ) ) {
|
||||
$form .= '<fieldset>';
|
||||
$form .= '<legend>' . $this->msg( 'requestaccount-leg-other' )->escaped() . '</legend>';
|
||||
$form .= $this->msg( 'requestaccount-ext-text' )->parseAsBlock() . "\n";
|
||||
if ( $this->hasItem( 'Notes' ) ) {
|
||||
$form .= "<p>" . $this->msg( 'requestaccount-notes' )->escaped() . "\n";
|
||||
$form .= "<textarea tabindex='1' name='wpNotes' id='wpNotes' rows='3' cols='80' style='width:100%;background-color:#f9f9f9;'>" .
|
||||
htmlspecialchars( $this->mNotes ) .
|
||||
"</textarea></p>\n";
|
||||
}
|
||||
$form .= '</fieldset>';
|
||||
}
|
||||
|
||||
if ( $this->hasItem( 'TermsOfService' ) ) {
|
||||
$form .= '<fieldset>';
|
||||
$form .= '<legend>' . $this->msg( 'requestaccount-leg-tos' )->escaped() . '</legend>';
|
||||
$form .= "<p>" . Xml::check( 'wpToS', $this->mToS, array( 'id' => 'wpToS' ) ) .
|
||||
' <label for="wpToS">' . $this->msg( 'requestaccount-tos' )->parse() . "</label></p>\n";
|
||||
$form .= '</fieldset>';
|
||||
}
|
||||
|
||||
//Scratch user verification
|
||||
$form .= '<fieldset>';
|
||||
$form .= '<legend>User verification</legend>';
|
||||
$form .= '<p>Please go to the <a href="http://scratch.mit.edu/projects/10135908/">user verification project</a> and comment the following code:<br /><b>' . sha1($_SERVER['REMOTE_ADDR'] . date('m')) . '</b></p>' . "\n";
|
||||
$form .= '</fieldset>';
|
||||
|
||||
# FIXME: do this better...
|
||||
global $wgConfirmAccountCaptchas, $wgCaptchaClass, $wgCaptchaTriggers;
|
||||
if ( $wgConfirmAccountCaptchas && isset( $wgCaptchaClass )
|
||||
&& $wgCaptchaTriggers['createaccount'] && !$reqUser->isAllowed( 'skipcaptcha' ) )
|
||||
{
|
||||
$captcha = new $wgCaptchaClass;
|
||||
# Hook point to add captchas
|
||||
$form .= '<fieldset>';
|
||||
$form .= $this->msg( 'captcha-createaccount' )->parseAsBlock();
|
||||
$form .= $captcha->getForm();
|
||||
$form .= '</fieldset>';
|
||||
}
|
||||
$form .= Html::Hidden( 'title', $this->getTitle()->getPrefixedDBKey() ) . "\n";
|
||||
$form .= Html::Hidden( 'wpEditToken', $reqUser->getEditToken() ) . "\n";
|
||||
$form .= Html::Hidden( 'attachment', $this->mPrevAttachment ) . "\n";
|
||||
$form .= Html::Hidden( 'forgotAttachment', $this->mForgotAttachment ) . "\n";
|
||||
$form .= "<p>" . Xml::submitButton( $this->msg( 'requestaccount-submit' )->text() ) . "</p>";
|
||||
$form .= Xml::closeElement( 'form' );
|
||||
|
||||
$out->addHTML( $form );
|
||||
|
||||
$out->addWikiMsg( 'requestaccount-footer' );
|
||||
}
|
||||
|
||||
protected function hasItem( $name ) {
|
||||
global $wgConfirmAccountRequestFormItems;
|
||||
|
||||
return $wgConfirmAccountRequestFormItems[$name]['enabled'];
|
||||
}
|
||||
|
||||
protected function doSubmit() {
|
||||
# Now create a dummy user ($u) and check if it is valid
|
||||
$name = trim( $this->mUsername );
|
||||
$u = User::newFromName( $name, 'creatable' );
|
||||
if ( !$u ) {
|
||||
$this->showForm( $this->msg( 'noname' )->escaped() );
|
||||
return;
|
||||
}
|
||||
# Set some additional data so the AbortNewAccount hook can be
|
||||
# used for more than just username validation
|
||||
$u->setEmail( $this->mEmail );
|
||||
$u->setRealName( $this->mRealName );
|
||||
# FIXME: Hack! If we don't want captchas for requests, temporarily turn it off!
|
||||
global $wgConfirmAccountCaptchas, $wgCaptchaTriggers;
|
||||
if ( !$wgConfirmAccountCaptchas && isset( $wgCaptchaTriggers ) ) {
|
||||
$old = $wgCaptchaTriggers['createaccount'];
|
||||
$wgCaptchaTriggers['createaccount'] = false;
|
||||
}
|
||||
$abortError = '';
|
||||
if ( !wfRunHooks( 'AbortNewAccount', array( $u, &$abortError ) ) ) {
|
||||
// Hook point to add extra creation throttles and blocks
|
||||
wfDebug( "RequestAccount::doSubmit: a hook blocked creation\n" );
|
||||
$this->showForm( $abortError );
|
||||
return;
|
||||
}
|
||||
# Set it back!
|
||||
if ( !$wgConfirmAccountCaptchas && isset( $wgCaptchaTriggers ) ) {
|
||||
$wgCaptchaTriggers['createaccount'] = $old;
|
||||
}
|
||||
|
||||
# Build submission object...
|
||||
$areaSet = array(); // make a simple list of interests
|
||||
foreach ( $this->mAreas as $area => $val ) {
|
||||
if ( $val > 0 ) {
|
||||
$areaSet[] = $area;
|
||||
}
|
||||
}
|
||||
|
||||
$submission = new AccountRequestSubmission(
|
||||
$this->getUser(),
|
||||
array(
|
||||
'userName' => $name,
|
||||
'realName' => $this->mRealName,
|
||||
'tosAccepted' => $this->mToS,
|
||||
'email' => $this->mEmail,
|
||||
'bio' => $this->mBio,
|
||||
'notes' => $this->mNotes,
|
||||
'urls' => $this->mUrls,
|
||||
'type' => $this->mType,
|
||||
'areas' => $areaSet,
|
||||
'registration' => wfTimestampNow(),
|
||||
'ip' => $this->getRequest()->getIP(),
|
||||
'xff' => $this->getRequest()->getHeader( 'X-Forwarded-For' ),
|
||||
'agent' => $this->getRequest()->getHeader( 'User-Agent' ),
|
||||
'attachmentPrevName' => $this->mPrevAttachment,
|
||||
'attachmentSrcName' => $this->mSrcName,
|
||||
'attachmentDidNotForget' => $this->mForgotAttachment, // confusing name :)
|
||||
'attachmentSize' => $this->mFileSize,
|
||||
'attachmentTempPath' => $this->mTempPath
|
||||
)
|
||||
);
|
||||
|
||||
# Actually submit!
|
||||
list( $status, $msg ) = $submission->submit( $this->getContext() );
|
||||
# Account for state changes
|
||||
$this->mForgotAttachment = $submission->getAttachmentDidNotForget();
|
||||
$this->mPrevAttachment = $submission->getAttachtmentPrevName();
|
||||
# Check for error messages
|
||||
if ( $status !== true ) {
|
||||
$this->showForm( $msg );
|
||||
return;
|
||||
}
|
||||
|
||||
# Done!
|
||||
$this->showSuccess();
|
||||
}
|
||||
|
||||
protected function showSuccess() {
|
||||
$out = $this->getOutput();
|
||||
$out->setPagetitle( $this->msg( "requestaccount" )->escaped() );
|
||||
$out->addWikiMsg( 'requestaccount-sent' );
|
||||
$out->addHTML(' If your request is accepted, your password will be <b>' . md5(strtolower(Title::newFromText($this->mUsername))) . '</b>.');
|
||||
$out->returnToMain();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the uploaded file from PHP data
|
||||
* @param $request WebRequest
|
||||
*/
|
||||
protected function initializeUpload( $request ) {
|
||||
$file = new WebRequestUpload( $request, 'wpUploadFile' );
|
||||
$this->mTempPath = $file->getTempName();
|
||||
$this->mFileSize = $file->getSize();
|
||||
$this->mSrcName = $file->getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* (a) Try to confirm an email address via a token
|
||||
* (b) Notify $wgConfirmAccountContact on success
|
||||
* @param $code string The token
|
||||
* @return void
|
||||
*/
|
||||
protected function confirmEmailToken( $code ) {
|
||||
global $wgConfirmAccountContact, $wgPasswordSender, $wgPasswordSenderName;
|
||||
|
||||
$reqUser = $this->getUser();
|
||||
$out = $this->getOutput();
|
||||
# Confirm if this token is in the pending requests
|
||||
$name = ConfirmAccount::requestNameFromEmailToken( $code );
|
||||
if ( $name !== false ) {
|
||||
# Send confirmation email to prospective user
|
||||
ConfirmAccount::confirmEmail( $name );
|
||||
# Send mail to admin after e-mail has been confirmed
|
||||
if ( $wgConfirmAccountContact != '' ) {
|
||||
$target = new MailAddress( $wgConfirmAccountContact );
|
||||
$source = new MailAddress( $wgPasswordSender, $wgPasswordSenderName );
|
||||
$title = SpecialPage::getTitleFor( 'ConfirmAccounts' );
|
||||
$subject = $this->msg( 'requestaccount-email-subj-admin' )->inContentLanguage()->escaped();
|
||||
$body = $this->msg(
|
||||
'requestaccount-email-body-admin', $name )->rawParams( $title->getFullUrl() )->inContentLanguage()->escaped();
|
||||
# Actually send the email...
|
||||
$result = UserMailer::send( $target, $source, $subject, $body );
|
||||
if ( !$result->isOK() ) {
|
||||
wfDebug( "Could not sent email to admin at $target\n" );
|
||||
}
|
||||
}
|
||||
$out->addWikiMsg( 'request-account-econf' );
|
||||
$out->returnToMain();
|
||||
} else {
|
||||
# Maybe the user confirmed after account was created...
|
||||
$user = User::newFromConfirmationCode( $code );
|
||||
if ( is_object( $user ) ) {
|
||||
if ( $user->confirmEmail() ) {
|
||||
$message = $reqUser->isLoggedIn()
|
||||
? 'confirmemail_loggedin'
|
||||
: 'confirmemail_success';
|
||||
$out->addWikiMsg( $message );
|
||||
if ( !$reqUser->isLoggedIn() ) {
|
||||
$title = SpecialPage::getTitleFor( 'Userlogin' );
|
||||
$out->returnToMain( true, $title->getPrefixedUrl() );
|
||||
}
|
||||
} else {
|
||||
$out->addWikiMsg( 'confirmemail_error' );
|
||||
}
|
||||
} else {
|
||||
$out->addWikiMsg( 'confirmemail_invalid' );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,233 @@
|
|||
<?php
|
||||
|
||||
class UserCredentialsPage extends SpecialPage {
|
||||
protected $target, $file;
|
||||
|
||||
function __construct() {
|
||||
parent::__construct( 'UserCredentials', 'lookupcredentials' );
|
||||
}
|
||||
|
||||
public function userCanExecute( User $user ) {
|
||||
global $wgConfirmAccountSaveInfo;
|
||||
return $wgConfirmAccountSaveInfo && parent::userCanExecute( $user );
|
||||
}
|
||||
|
||||
function execute( $par ) {
|
||||
$out = $this->getOutput();
|
||||
$request = $this->getRequest();
|
||||
$reqUser = $this->getUser();
|
||||
|
||||
if ( !$this->userCanExecute( $this->getUser() ) ) {
|
||||
throw new PermissionsError( 'lookupcredentials' );
|
||||
}
|
||||
|
||||
$this->setHeaders();
|
||||
|
||||
# A target user
|
||||
$this->target = $request->getText( 'target' );
|
||||
# Attachments
|
||||
$this->file = $request->getVal( 'file' );
|
||||
|
||||
if ( $this->file ) {
|
||||
$this->showFile( $this->file );
|
||||
} elseif ( $this->target ) {
|
||||
$this->showForm();
|
||||
$this->showCredentials();
|
||||
} else {
|
||||
$this->showForm();
|
||||
}
|
||||
$out->addModules( 'ext.confirmAccount' ); // CSS
|
||||
}
|
||||
|
||||
function showForm() {
|
||||
global $wgScript;
|
||||
$out = $this->getOutput();
|
||||
|
||||
$username = str_replace( '_', ' ', $this->target );
|
||||
$form = Xml::openElement( 'form', array( 'name' => 'stablization', 'action' => $wgScript, 'method' => 'get' ) );
|
||||
$form .= "<fieldset><legend>" . $this->msg( 'usercredentials-leg' )->escaped() . "</legend>";
|
||||
$form .= "<table><tr>";
|
||||
$form .= "<td>" . Html::Hidden( 'title', $this->getTitle()->getPrefixedText() ) . "</td>";
|
||||
$form .= "<td>" . $this->msg( "usercredentials-user" )->escaped() . "</td>";
|
||||
$form .= "<td>" . Xml::input( 'target', 35, $username, array( 'id' => 'wpUsername' ) ) . "</td>";
|
||||
$form .= "<td>" . Xml::submitButton( $this->msg( 'go' )->text() ) . "</td>";
|
||||
$form .= "</tr></table>";
|
||||
$form .= "</fieldset></form>\n";
|
||||
|
||||
$out->addHTML( $form );
|
||||
}
|
||||
|
||||
function showCredentials() {
|
||||
$reqUser = $this->getUser();
|
||||
$out = $this->getOutput();
|
||||
|
||||
$titleObj = SpecialPage::getTitleFor( 'UserCredentials' );
|
||||
|
||||
$row = $this->getAccountData();
|
||||
if ( !$row ) {
|
||||
$out->addHTML( $this->msg( 'usercredentials-badid' )->escaped() );
|
||||
return;
|
||||
}
|
||||
|
||||
$out->addWikiMsg( 'usercredentials-text' );
|
||||
|
||||
$user = User::newFromName( $this->target );
|
||||
|
||||
$list = array();
|
||||
foreach ( $user->getGroups() as $group ) {
|
||||
$list[] = User::makeGroupLinkHTML(
|
||||
$group,
|
||||
User::getGroupMember( $group, $user->getName() )
|
||||
);
|
||||
}
|
||||
|
||||
$grouplist = '';
|
||||
if ( count( $list ) > 0 ) {
|
||||
$grouplist = '<tr><td>' . $this->msg( 'usercredentials-member' )->escaped() . '</td><td>' . implode( ', ', $list ) . '</td></tr>';
|
||||
}
|
||||
|
||||
$form = "<fieldset>";
|
||||
$form .= '<legend>' . $this->msg( 'usercredentials-leg-user' )->escaped() . '</legend>';
|
||||
$form .= '<table cellpadding=\'4\'>';
|
||||
$form .= "<tr><td>" . $this->msg( 'username' )->escaped() . "</td>";
|
||||
$form .= "<td>" . Linker::makeLinkObj( $user->getUserPage(), htmlspecialchars( $user->getUserPage()->getText() ) ) . "</td></tr>\n";
|
||||
|
||||
$econf = $row->acd_email_authenticated ? ' <strong>' . $this->msg( 'confirmaccount-econf' )->escaped() . '</strong>' : '';
|
||||
$form .= "<tr><td>" . $this->msg( 'usercredentials-email' )->escaped() . "</td>";
|
||||
$form .= "<td>" . htmlspecialchars( $row->acd_email ) . $econf . "</td></tr>\n";
|
||||
|
||||
$form .= $grouplist;
|
||||
|
||||
$form .= '</table></fieldset>';
|
||||
|
||||
$areaSet = UserAccountRequest::expandAreas( $row->acd_areas );
|
||||
|
||||
$userAreas = ConfirmAccount::getUserAreaConfig();
|
||||
if ( count( $userAreas ) > 0 ) {
|
||||
$form .= '<fieldset>';
|
||||
$form .= '<legend>' . $this->msg( 'confirmaccount-leg-areas' )->escaped() . '</legend>';
|
||||
|
||||
$form .= "<div style='height:150px; overflow:scroll; background-color:#f9f9f9;'>";
|
||||
$form .= "<table cellspacing='5' cellpadding='0' style='background-color:#f9f9f9;'><tr valign='top'>";
|
||||
$count = 0;
|
||||
|
||||
$att = array( 'disabled' => 'disabled' );
|
||||
foreach ( $userAreas as $name => $conf ) {
|
||||
$count++;
|
||||
if ( $count > 5 ) {
|
||||
$form .= "</tr><tr valign='top'>";
|
||||
$count = 1;
|
||||
}
|
||||
$formName = "wpArea-" . htmlspecialchars( str_replace( ' ', '_', $name ) );
|
||||
if ( $conf['project'] != '' ) {
|
||||
$pg = Linker::linkKnown(
|
||||
Title::newFromText( $name ),
|
||||
$this->msg( 'requestaccount-info' )->escaped()
|
||||
);
|
||||
} else {
|
||||
$pg = '';
|
||||
}
|
||||
$form .= "<td>" .
|
||||
Xml::checkLabel( $name, $formName, $formName, in_array( $formName, $areaSet ), $att ) .
|
||||
" {$pg}</td>\n";
|
||||
}
|
||||
$form .= "</tr></table></div>";
|
||||
$form .= '</fieldset>';
|
||||
}
|
||||
|
||||
$form .= '<fieldset>';
|
||||
$form .= '<legend>' . $this->msg( 'usercredentials-leg-person' )->escaped() . '</legend>';
|
||||
$form .= '<table cellpadding=\'4\'>';
|
||||
$form .= "<tr><td>" . $this->msg( 'usercredentials-real' )->escaped() . "</td>";
|
||||
$form .= "<td>" . htmlspecialchars( $row->acd_real_name ) . "</td></tr>\n";
|
||||
$form .= '</table>';
|
||||
$form .= "<p>" . $this->msg( 'usercredentials-bio' )->escaped() . "</p>";
|
||||
$form .= "<p><textarea tabindex='1' readonly='readonly' name='wpBio' id='wpNewBio' rows='10' cols='80' style='width:100%'>" .
|
||||
htmlspecialchars( $row->acd_bio ) .
|
||||
"</textarea></p>\n";
|
||||
$form .= '</fieldset>';
|
||||
|
||||
$form .= '<fieldset>';
|
||||
$form .= '<legend>' . $this->msg( 'usercredentials-leg-other' )->escaped() . '</legend>';
|
||||
if ( $this->hasItem( 'CV' ) || $this->hasItem( 'Notes' ) || $this->hasItem( 'Links' ) ) {
|
||||
$form .= '<p>' . $this->msg( 'usercredentials-attach' )->escaped() . ' ';
|
||||
if ( $row->acd_filename ) {
|
||||
$form .= Linker::makeKnownLinkObj( $titleObj, htmlspecialchars( $row->acd_filename ),
|
||||
'file=' . $row->acd_storage_key );
|
||||
} else {
|
||||
$form .= $this->msg( 'confirmaccount-none-p' )->escaped();
|
||||
}
|
||||
$form .= "</p><p>" . $this->msg( 'usercredentials-notes' )->escaped() . "</p>\n";
|
||||
$form .= "<p><textarea tabindex='1' readonly='readonly' name='wpNotes' id='wpNotes' rows='3' cols='80' style='width:100%'>" .
|
||||
htmlspecialchars( $row->acd_notes ) .
|
||||
"</textarea></p>\n";
|
||||
$form .= "<p>" . $this->msg( 'usercredentials-urls' )->escaped() . "</p>\n";
|
||||
$form .= ConfirmAccountsPage::parseLinks( $row->acd_urls );
|
||||
}
|
||||
$form .= '</fieldset>';
|
||||
|
||||
if ( $reqUser->isAllowed( 'requestips' ) ) {
|
||||
$form .= '<fieldset>';
|
||||
$form .= '<legend>' . $this->msg( 'usercredentials-leg-ip' )->escaped() . '</legend>';
|
||||
$form .= "<p>" . $this->msg( 'usercredentials-ip' )->escaped() .
|
||||
" " . htmlspecialchars( $row->acd_ip ) . "</p>\n";
|
||||
if ( $row->acd_xff ) {
|
||||
$form .= "<p>" . $this->msg( 'usercredentials-xff' )->escaped() .
|
||||
" " . htmlspecialchars( $row->acd_xff ) . "</p>\n";
|
||||
}
|
||||
if ( $row->acd_agent ) {
|
||||
$form .= "<p>" . $this->msg( 'usercredentials-agent' )->escaped() .
|
||||
" " . htmlspecialchars( $row->acd_agent ) . "</p>\n";
|
||||
}
|
||||
$form .= '</fieldset>';
|
||||
}
|
||||
|
||||
$out->addHTML( $form );
|
||||
}
|
||||
|
||||
protected function hasItem( $name ) {
|
||||
global $wgConfirmAccountRequestFormItems;
|
||||
|
||||
return $wgConfirmAccountRequestFormItems[$name]['enabled'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a private file requested by the visitor.
|
||||
* @param $key string
|
||||
* @return void
|
||||
*/
|
||||
function showFile( $key ) {
|
||||
global $wgConfirmAccountFSRepos;
|
||||
$out = $this->getOutput();
|
||||
$request = $this->getRequest();
|
||||
|
||||
$out->disable();
|
||||
|
||||
# We mustn't allow the output to be Squid cached, otherwise
|
||||
# if an admin previews a private image, and it's cached, then
|
||||
# a user without appropriate permissions can toddle off and
|
||||
# nab the image, and Squid will serve it
|
||||
$request->response()->header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', 0 ) . ' GMT' );
|
||||
$request->response()->header( 'Cache-Control: no-cache, no-store, max-age=0, must-revalidate' );
|
||||
$request->response()->header( 'Pragma: no-cache' );
|
||||
|
||||
$repo = new FSRepo( $wgConfirmAccountFSRepos['accountcreds'] );
|
||||
$path = $repo->getZonePath( 'public' ) . '/' .
|
||||
UserAccountRequest::relPathFromKey( $key );
|
||||
|
||||
$repo->streamFile( $path );
|
||||
}
|
||||
|
||||
function getAccountData() {
|
||||
$uid = User::idFromName( $this->target );
|
||||
if ( !$uid )
|
||||
return false;
|
||||
# For now, just get the first revision...
|
||||
$dbr = wfGetDB( DB_SLAVE );
|
||||
$row = $dbr->selectRow( 'account_credentials', '*',
|
||||
array( 'acd_user_id' => $uid ),
|
||||
__METHOD__,
|
||||
array( 'ORDER BY' => 'acd_user_id,acd_id ASC' ) );
|
||||
return $row;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue