user.php
来自「php 开发的内容管理系统」· PHP 代码 · 共 2,044 行 · 第 1/4 页
PHP
2,044 行
<?php
/**
* See user.txt
*
* @package MediaWiki
*/
# Number of characters in user_token field
define( 'USER_TOKEN_LENGTH', 32 );
# Serialized record version
define( 'MW_USER_VERSION', 3 );
/**
*
* @package MediaWiki
*/
class User {
/*
* When adding a new private variable, dont forget to add it to __sleep()
*/
/**@{{
* @private
*/
var $mBlockedby; //!<
var $mBlockreason; //!<
var $mDataLoaded; //!<
var $mEmail; //!<
var $mEmailAuthenticated; //!<
var $mGroups; //!<
var $mHash; //!<
var $mId; //!<
var $mName; //!<
var $mNewpassword; //!<
var $mNewtalk; //!<
var $mOptions; //!<
var $mPassword; //!<
var $mRealName; //!<
var $mRegistration; //!<
var $mRights; //!<
var $mSkin; //!<
var $mToken; //!<
var $mTouched; //!<
var $mVersion; //!< serialized version
/**@}} */
/** Constructor using User:loadDefaults() */
function User() {
$this->loadDefaults();
$this->mVersion = MW_USER_VERSION;
}
/**
* Static factory method
* @param string $name Username, validated by Title:newFromText()
* @param bool $validate Validate username
* @return User
* @static
*/
function newFromName( $name, $validate = true ) {
# Force usernames to capital
global $wgContLang;
// Modified for mediawiki for XOOPS - by D.J.
//$name = $wgContLang->ucfirst( $name );
# Clean up name according to title rules
$t = Title::newFromText( $name );
if( is_null( $t ) ) {
return null;
}
# Reject various classes of invalid names
$canonicalName = $t->getText();
global $wgAuth;
$canonicalName = $wgAuth->getCanonicalName( $t->getText() );
if( $validate && !User::isValidUserName( $canonicalName ) ) {
return null;
}
$u = new User();
$u->setName( $canonicalName );
$u->setId( $u->idFromName( $canonicalName ) );
return $u;
}
/**
* Factory method to fetch whichever use has a given email confirmation code.
* This code is generated when an account is created or its e-mail address
* has changed.
*
* If the code is invalid or has expired, returns NULL.
*
* @param string $code
* @return User
* @static
*/
function newFromConfirmationCode( $code ) {
$dbr =& wfGetDB( DB_SLAVE );
$name = $dbr->selectField( 'user', 'user_name', array(
'user_email_token' => md5( $code ),
'user_email_token_expires > ' . $dbr->addQuotes( $dbr->timestamp() ),
) );
if( is_string( $name ) ) {
return User::newFromName( $name );
} else {
return null;
}
}
/**
* Serialze sleep function, for better cache efficiency and avoidance of
* silly "incomplete type" errors when skins are cached. The array should
* contain names of private variables (see at top of User.php).
*/
function __sleep() {
return array(
'mBlockedby',
'mBlockreason',
'mDataLoaded',
'mEmail',
'mEmailAuthenticated',
'mGroups',
'mHash',
'mId',
'mName',
'mNewpassword',
'mNewtalk',
'mOptions',
'mPassword',
'mRealName',
'mRegistration',
'mRights',
'mToken',
'mTouched',
'mVersion',
);
}
/**
* Get username given an id.
* @param integer $id Database user id
* @return string Nickname of a user
* @static
*/
function whoIs( $id ) {
// Modified for mediawiki for XOOPS - by D.J.
if(is_object($GLOBALS["xoopsUser"]) && $id == $GLOBALS["xoopsUser"]->getVar("uid")){
$xoopsuser =& $GLOBALS["xoopsUser"];
}else{
$member_handler =& xoops_getHandler("member");
$xoopsuser =& $member_handler->getUser($id);
}
//if(is_object($xoopsuser)) return MEDIAWIKI_USERPREFIX.mediawiki_encoding_xoops2mediawiki($xoopsuser->getVar("uname"));
if(is_object($xoopsuser)) return mediawiki_username_xoops2mediawiki($xoopsuser->getVar("uname"));
else return 0;
$dbr =& wfGetDB( DB_SLAVE );
return $dbr->selectField( 'user', 'user_name', array( 'user_id' => $id ), 'User::whoIs' );
}
/**
* Get real username given an id.
* @param integer $id Database user id
* @return string Realname of a user
* @static
*/
function whoIsReal( $id ) {
// Modified for mediawiki for XOOPS - by D.J.
if(is_object($GLOBALS["xoopsUser"]) && $id == $GLOBALS["xoopsUser"]->getVar("uid")){
$xoopsuser =& $GLOBALS["xoopsUser"];
}else{
$member_handler =& xoops_getHandler("member");
$xoopsuser =& $member_handler->getUser($id);
}
if(is_object($xoopsuser)) {
$realname = $xoopsuser->getVar("name")?$xoopsuser->getVar("name"):$xoopsuser->getVar("uname");
//return MEDIAWIKI_USERPREFIX.mediawiki_encoding_xoops2mediawiki($realname);
return mediawiki_username_xoops2mediawiki($realname);
}
else return 0;
$dbr =& wfGetDB( DB_SLAVE );
return $dbr->selectField( 'user', 'user_real_name', array( 'user_id' => $id ), 'User::whoIsReal' );
}
/**
* Get database id given a user name
* @param string $name Nickname of a user
* @return integer|null Database user id (null: if non existent
* @static
*/
function idFromName( $name ) {
$fname = "User::idFromName";
$nt = Title::newFromText( $name );
if( is_null( $nt ) ) {
# Illegal name
return null;
}
// Modified for mediawiki for XOOPS - by D.J.
//$name = preg_replace("/^".preg_quote(MEDIAWIKI_USERPREFIX)."/", "", $name);
$user_handler =& xoops_getHandler("user");
$xoopsusers = array_keys($user_handler->getObjects(new Criteria("uname", mediawiki_username_mediawiki2xoops($name)), 1));
if(empty($xoopsusers)) return null;
else return $xoopsusers[0];
$dbr =& wfGetDB( DB_SLAVE );
$s = $dbr->selectRow( 'user', array( 'user_id' ), array( 'user_name' => $nt->getText() ), $fname );
if ( $s === false ) {
return 0;
} else {
return $s->user_id;
}
}
/**
* Does the string match an anonymous IPv4 address?
*
* This function exists for username validation, in order to reject
* usernames which are similar in form to IP addresses. Strings such
* as 300.300.300.300 will return true because it looks like an IP
* address, despite not being strictly valid.
*
* We match \d{1,3}\.\d{1,3}\.\d{1,3}\.xxx as an anonymous IP
* address because the usemod software would "cloak" anonymous IP
* addresses like this, if we allowed accounts like this to be created
* new users could get the old edits of these anonymous users.
*
* @bug 3631
*
* @static
* @param string $name Nickname of a user
* @return bool
*/
function isIP( $name ) {
return preg_match("/^\d{1,3}\.\d{1,3}\.\d{1,3}\.(?:xxx|\d{1,3})$/",$name);
/*return preg_match("/^
(?:[01]?\d{1,2}|2(:?[0-4]\d|5[0-5]))\.
(?:[01]?\d{1,2}|2(:?[0-4]\d|5[0-5]))\.
(?:[01]?\d{1,2}|2(:?[0-4]\d|5[0-5]))\.
(?:[01]?\d{1,2}|2(:?[0-4]\d|5[0-5]))
$/x", $name);*/
}
/**
* Is the input a valid username?
*
* Checks if the input is a valid username, we don't want an empty string,
* an IP address, anything that containins slashes (would mess up subpages),
* is longer than the maximum allowed username size or doesn't begin with
* a capital letter.
*
* @param string $name
* @return bool
* @static
*/
function isValidUserName( $name ) {
global $wgContLang, $wgMaxNameChars;
// Modified for mediawiki for XOOPS - by D.J.
if ( $name == ''
|| User::isIP( $name )
|| strpos( $name, '/' ) !== false
|| strlen( $name ) > $wgMaxNameChars
//|| $name != $wgContLang->ucfirst( $name )
)
return false;
// Ensure that the name can't be misresolved as a different title,
// such as with extra namespace keys at the start.
$parsed = Title::newFromText( $name );
if( is_null( $parsed )
|| $parsed->getNamespace()
|| strcmp( $name, $parsed->getPrefixedText() ) )
return false;
// Check an additional blacklist of troublemaker characters.
// Should these be merged into the title char list?
$unicodeBlacklist = '/[' .
'\x{0080}-\x{009f}' . # iso-8859-1 control chars
'\x{00a0}' . # non-breaking space
'\x{2000}-\x{200f}' . # various whitespace
'\x{2028}-\x{202f}' . # breaks and control chars
'\x{3000}' . # ideographic space
'\x{e000}-\x{f8ff}' . # private use
']/u';
if( preg_match( $unicodeBlacklist, $name ) ) {
return false;
}
return true;
}
/**
* Is the input a valid password?
*
* @param string $password
* @return bool
* @static
*/
function isValidPassword( $password ) {
global $wgMinimalPasswordLength;
return strlen( $password ) >= $wgMinimalPasswordLength;
}
/**
* Does the string match roughly an email address ?
*
* There used to be a regular expression here, it got removed because it
* rejected valid addresses. Actually just check if there is '@' somewhere
* in the given address.
*
* @todo Check for RFC 2822 compilance
* @bug 959
*
* @param string $addr email address
* @static
* @return bool
*/
function isValidEmailAddr ( $addr ) {
return ( trim( $addr ) != '' ) &&
(false !== strpos( $addr, '@' ) );
}
/**
* Count the number of edits of a user
*
* @param int $uid The user ID to check
* @return int
*/
function edits( $uid ) {
$fname = 'User::edits';
$dbr =& wfGetDB( DB_SLAVE );
return $dbr->selectField(
'revision', 'count(*)',
array( 'rev_user' => $uid ),
$fname
);
}
/**
* probably return a random password
* @return string probably a random password
* @static
* @todo Check what is doing really [AV]
*/
function randomPassword() {
global $wgMinimalPasswordLength;
$pwchars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz';
$l = strlen( $pwchars ) - 1;
$pwlength = max( 7, $wgMinimalPasswordLength );
$digit = mt_rand(0, $pwlength - 1);
$np = '';
for ( $i = 0; $i < $pwlength; $i++ ) {
$np .= $i == $digit ? chr( mt_rand(48, 57) ) : $pwchars{ mt_rand(0, $l)};
}
return $np;
}
/**
* Set properties to default
* Used at construction. It will load per language default settings only
* if we have an available language object.
*/
function loadDefaults() {
static $n=0;
$n++;
$fname = 'User::loadDefaults' . $n;
wfProfileIn( $fname );
global $wgCookiePrefix;
global $wgNamespacesToBeSearchedDefault;
$this->mId = 0;
$this->mNewtalk = -1;
$this->mName = false;
$this->mRealName = $this->mEmail = '';
$this->mEmailAuthenticated = null;
$this->mPassword = $this->mNewpassword = '';
$this->mRights = array();
$this->mGroups = array();
$this->mOptions = User::getDefaultOptions();
foreach( $wgNamespacesToBeSearchedDefault as $nsnum => $val ) {
$this->mOptions['searchNs'.$nsnum] = $val;
}
unset( $this->mSkin );
$this->mDataLoaded = false;
$this->mBlockedby = -1; # Unset
$this->setToken(); # Random
$this->mHash = false;
if ( isset( $_COOKIE[$wgCookiePrefix.'LoggedOut'] ) ) {
$this->mTouched = wfTimestamp( TS_MW, $_COOKIE[$wgCookiePrefix.'LoggedOut'] );
}
else {
$this->mTouched = '0'; # Allow any pages to be cached
}
$this->mRegistration = wfTimestamp( TS_MW );
wfProfileOut( $fname );
}
/**
* Combine the language default options with any site-specific options
* and add the default language variants.
*
* @return array
* @static
* @private
*/
function getDefaultOptions() {
/**
* Site defaults will override the global/language defaults
*/
global $wgContLang, $wgDefaultUserOptions;
$defOpt = $wgDefaultUserOptions + $wgContLang->getDefaultUserOptions();
/**
* default language setting
*/
$variant = $wgContLang->getPreferredVariant();
$defOpt['variant'] = $variant;
$defOpt['language'] = $variant;
return $defOpt;
}
/**
* Get a given default option value.
*
* @param string $opt
* @return string
* @static
* @public
*/
function getDefaultOption( $opt ) {
$defOpts = User::getDefaultOptions();
if( isset( $defOpts[$opt] ) ) {
return $defOpts[$opt];
} else {
return '';
}
}
/**
* Get blocking information
* @private
* @param bool $bFromSlave Specify whether to check slave or master. To improve performance,
* non-critical checks are done against slaves. Check when actually saving should be done against
* master.
*/
function getBlockedStatus( $bFromSlave = true ) {
global $wgEnableSorbs, $wgProxyWhitelist;
if ( -1 != $this->mBlockedby ) {
wfDebug( "User::getBlockedStatus: already loaded.\n" );
return;
}
$fname = 'User::getBlockedStatus';
wfProfileIn( $fname );
wfDebug( "$fname: checking...\n" );
$this->mBlockedby = 0;
$ip = wfGetIP();
# User/IP blocking
$block = new Block();
$block->fromMaster( !$bFromSlave );
if ( $block->load( $ip , $this->mId ) ) {
wfDebug( "$fname: Found block.\n" );
$this->mBlockedby = $block->mBy;
$this->mBlockreason = $block->mReason;
if ( $this->isLoggedIn() ) {
$this->spreadBlock();
}
} else {
wfDebug( "$fname: No block.\n" );
}
# Proxy blocking
# FIXME ? proxyunbannable is to deprecate the old isSysop()
if ( !$this->isAllowed('proxyunbannable') && !in_array( $ip, $wgProxyWhitelist ) ) {
# Local list
if ( wfIsLocallyBlockedProxy( $ip ) ) {
$this->mBlockedby = wfMsg( 'proxyblocker' );
$this->mBlockreason = wfMsg( 'proxyblockreason' );
}
# DNSBL
if ( !$this->mBlockedby && $wgEnableSorbs && !$this->getID() ) {
if ( $this->inSorbsBlacklist( $ip ) ) {
$this->mBlockedby = wfMsg( 'sorbs' );
$this->mBlockreason = wfMsg( 'sorbsreason' );
}
}
}
# Extensions
wfRunHooks( 'GetBlockedStatus', array( &$this ) );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?