user.php
来自「php 开发的内容管理系统」· PHP 代码 · 共 2,044 行 · 第 1/4 页
PHP
2,044 行
wfProfileOut( $fname );
}
function inSorbsBlacklist( $ip ) {
global $wgEnableSorbs;
return $wgEnableSorbs &&
$this->inDnsBlacklist( $ip, 'http.dnsbl.sorbs.net.' );
}
function inDnsBlacklist( $ip, $base ) {
$fname = 'User::inDnsBlacklist';
wfProfileIn( $fname );
$found = false;
$host = '';
if ( preg_match( '/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/', $ip, $m ) ) {
# Make hostname
for ( $i=4; $i>=1; $i-- ) {
$host .= $m[$i] . '.';
}
$host .= $base;
# Send query
$ipList = gethostbynamel( $host );
if ( $ipList ) {
wfDebug( "Hostname $host is {$ipList[0]}, it's a proxy says $base!\n" );
$found = true;
} else {
wfDebug( "Requested $host, not found in $base.\n" );
}
}
wfProfileOut( $fname );
return $found;
}
/**
* Primitive rate limits: enforce maximum actions per time period
* to put a brake on flooding.
*
* Note: when using a shared cache like memcached, IP-address
* last-hit counters will be shared across wikis.
*
* @return bool true if a rate limiter was tripped
* @public
*/
function pingLimiter( $action='edit' ) {
global $wgRateLimits, $wgRateLimitsExcludedGroups;
if( !isset( $wgRateLimits[$action] ) ) {
return false;
}
# Some groups shouldn't trigger the ping limiter, ever
foreach( $this->getGroups() as $group ) {
if( array_search( $group, $wgRateLimitsExcludedGroups ) !== false )
return false;
}
global $wgMemc, $wgDBname, $wgRateLimitLog;
$fname = 'User::pingLimiter';
wfProfileIn( $fname );
$limits = $wgRateLimits[$action];
$keys = array();
$id = $this->getId();
$ip = wfGetIP();
if( isset( $limits['anon'] ) && $id == 0 ) {
$keys["$wgDBname:limiter:$action:anon"] = $limits['anon'];
}
if( isset( $limits['user'] ) && $id != 0 ) {
$keys["$wgDBname:limiter:$action:user:$id"] = $limits['user'];
}
if( $this->isNewbie() ) {
if( isset( $limits['newbie'] ) && $id != 0 ) {
$keys["$wgDBname:limiter:$action:user:$id"] = $limits['newbie'];
}
if( isset( $limits['ip'] ) ) {
$keys["mediawiki:limiter:$action:ip:$ip"] = $limits['ip'];
}
if( isset( $limits['subnet'] ) && preg_match( '/^(\d+\.\d+\.\d+)\.\d+$/', $ip, $matches ) ) {
$subnet = $matches[1];
$keys["mediawiki:limiter:$action:subnet:$subnet"] = $limits['subnet'];
}
}
$triggered = false;
foreach( $keys as $key => $limit ) {
list( $max, $period ) = $limit;
$summary = "(limit $max in {$period}s)";
$count = $wgMemc->get( $key );
if( $count ) {
if( $count > $max ) {
wfDebug( "$fname: tripped! $key at $count $summary\n" );
if( $wgRateLimitLog ) {
@error_log( wfTimestamp( TS_MW ) . ' ' . $wgDBname . ': ' . $this->getName() . " tripped $key at $count $summary\n", 3, $wgRateLimitLog );
}
$triggered = true;
} else {
wfDebug( "$fname: ok. $key at $count $summary\n" );
}
} else {
wfDebug( "$fname: adding record for $key $summary\n" );
$wgMemc->add( $key, 1, intval( $period ) );
}
$wgMemc->incr( $key );
}
wfProfileOut( $fname );
return $triggered;
}
/**
* Check if user is blocked
* @return bool True if blocked, false otherwise
*/
function isBlocked( $bFromSlave = true ) { // hacked from false due to horrible probs on site
wfDebug( "User::isBlocked: enter\n" );
$this->getBlockedStatus( $bFromSlave );
return $this->mBlockedby !== 0;
}
/**
* Check if user is blocked from editing a particular article
*/
function isBlockedFrom( $title, $bFromSlave = false ) {
global $wgBlockAllowsUTEdit;
$fname = 'User::isBlockedFrom';
wfProfileIn( $fname );
wfDebug( "$fname: enter\n" );
if ( $wgBlockAllowsUTEdit && $title->getText() === $this->getName() &&
$title->getNamespace() == NS_USER_TALK )
{
$blocked = false;
wfDebug( "$fname: self-talk page, ignoring any blocks\n" );
} else {
wfDebug( "$fname: asking isBlocked()\n" );
$blocked = $this->isBlocked( $bFromSlave );
}
wfProfileOut( $fname );
return $blocked;
}
/**
* Get name of blocker
* @return string name of blocker
*/
function blockedBy() {
$this->getBlockedStatus();
return $this->mBlockedby;
}
/**
* Get blocking reason
* @return string Blocking reason
*/
function blockedFor() {
$this->getBlockedStatus();
return $this->mBlockreason;
}
/**
* Initialise php session
*/
function SetupSession() {
// Modified for mediawiki for XOOPS - by D.J.
return;
global $wgSessionsInMemcached, $wgCookiePath, $wgCookieDomain;
if( $wgSessionsInMemcached ) {
require_once( 'MemcachedSessions.php' );
} elseif( 'files' != ini_get( 'session.save_handler' ) ) {
# If it's left on 'user' or another setting from another
# application, it will end up failing. Try to recover.
ini_set ( 'session.save_handler', 'files' );
}
session_set_cookie_params( 0, $wgCookiePath, $wgCookieDomain );
session_cache_limiter( 'private, must-revalidate' );
@session_start();
}
/**
* Create a new user object using data from session
* @static
*/
function loadFromSession() {
// Modified for mediawiki for XOOPS - by D.J.
return $this->loadFromDatabase();
global $wgMemc, $wgDBname, $wgCookiePrefix;
if ( isset( $_SESSION['wsUserID'] ) ) {
if ( 0 != $_SESSION['wsUserID'] ) {
$sId = $_SESSION['wsUserID'];
} else {
return new User();
}
} else if ( isset( $_COOKIE["{$wgCookiePrefix}UserID"] ) ) {
$sId = intval( $_COOKIE["{$wgCookiePrefix}UserID"] );
$_SESSION['wsUserID'] = $sId;
} else {
return new User();
}
if ( isset( $_SESSION['wsUserName'] ) ) {
$sName = $_SESSION['wsUserName'];
} else if ( isset( $_COOKIE["{$wgCookiePrefix}UserName"] ) ) {
$sName = $_COOKIE["{$wgCookiePrefix}UserName"];
$_SESSION['wsUserName'] = $sName;
} else {
return new User();
}
$passwordCorrect = FALSE;
$user = $wgMemc->get( $key = "$wgDBname:user:id:$sId" );
if( !is_object( $user ) || $user->mVersion < MW_USER_VERSION ) {
# Expire old serialized objects; they may be corrupt.
$user = false;
}
if($makenew = !$user) {
wfDebug( "User::loadFromSession() unable to load from memcached\n" );
$user = new User();
$user->mId = $sId;
$user->loadFromDatabase();
} else {
wfDebug( "User::loadFromSession() got from cache!\n" );
}
if ( isset( $_SESSION['wsToken'] ) ) {
$passwordCorrect = $_SESSION['wsToken'] == $user->mToken;
} else if ( isset( $_COOKIE["{$wgCookiePrefix}Token"] ) ) {
$passwordCorrect = $user->mToken == $_COOKIE["{$wgCookiePrefix}Token"];
} else {
return new User(); # Can't log in from session
}
if ( ( $sName == $user->mName ) && $passwordCorrect ) {
if($makenew) {
if($wgMemc->set( $key, $user ))
wfDebug( "User::loadFromSession() successfully saved user\n" );
else
wfDebug( "User::loadFromSession() unable to save to memcached\n" );
}
return $user;
}
return new User(); # Can't log in from session
}
/**
* Load a user from the database
*/
function loadFromDatabase() {
$fname = "User::loadFromDatabase";
# Counter-intuitive, breaks various things, use User::setLoaded() if you want to suppress
# loading in a command line script, don't assume all command line scripts need it like this
#if ( $this->mDataLoaded || $wgCommandLineMode ) {
if ( $this->mDataLoaded ) {
return;
}
# Paranoia
$this->mId = intval( $this->mId );
/** Anonymous user */
if( !$this->mId ) {
/** Get rights */
$this->mRights = $this->getGroupPermissions( array( '*' ) );
$this->mDataLoaded = true;
return;
} # the following stuff is for non-anonymous users only
$dbr =& wfGetDB( DB_SLAVE );
$s = $dbr->selectRow( 'user', array( 'user_name','user_password','user_newpassword','user_email',
'user_email_authenticated',
'user_real_name','user_options','user_touched', 'user_token', 'user_registration' ),
array( 'user_id' => $this->mId ), $fname );
if ( $s !== false ) {
$this->mName = $s->user_name;
$this->mEmail = $s->user_email;
$this->mEmailAuthenticated = wfTimestampOrNull( TS_MW, $s->user_email_authenticated );
$this->mRealName = $s->user_real_name;
$this->mPassword = $s->user_password;
$this->mNewpassword = $s->user_newpassword;
$this->decodeOptions( $s->user_options );
$this->mTouched = wfTimestamp(TS_MW,$s->user_touched);
$this->mToken = $s->user_token;
$this->mRegistration = wfTimestampOrNull( TS_MW, $s->user_registration );
$res = $dbr->select( 'user_groups',
array( 'ug_group' ),
array( 'ug_user' => $this->mId ),
$fname );
$this->mGroups = array();
while( $row = $dbr->fetchObject( $res ) ) {
$this->mGroups[] = $row->ug_group;
}
$implicitGroups = array( '*', 'user' );
global $wgAutoConfirmAge;
$accountAge = time() - wfTimestampOrNull( TS_UNIX, $this->mRegistration );
if( $accountAge >= $wgAutoConfirmAge ) {
$implicitGroups[] = 'autoconfirmed';
}
$effectiveGroups = array_merge( $implicitGroups, $this->mGroups );
$this->mRights = $this->getGroupPermissions( $effectiveGroups );
}
// Modified for mediawiki for XOOPS - by D.J.
if(is_object($GLOBALS["xoopsUser"]) && $this->mId == $GLOBALS["xoopsUser"]->getVar("uid")){
$xoopsuser =& $GLOBALS["xoopsUser"];
}else{
$member_handler =& xoops_getHandler("member");
$xoopsuser =& $member_handler->getUser($this->mId);
}
if ( is_object($xoopsuser) ) {
$this->mName = mediawiki_username_xoops2mediawiki($xoopsuser->getVar("uname"));
$this->mEmail = $xoopsuser->getVar("email");
$realname = $xoopsuser->getVar("name")?$xoopsuser->getVar("name"):$xoopsuser->getVar("uname");
$this->mRealName = mediawiki_username_xoops2mediawiki($realname);
if($xoopsuser->isAdmin()){
$this->mGroups[] = 'sysop';
}
$effectiveGroups = array_merge( array( '*', 'user' ), $this->mGroups );
$this->mRights = $this->getGroupPermissions( $effectiveGroups );
}
$this->mDataLoaded = true;
}
function getID() { return $this->mId; }
function setID( $v ) {
$this->mId = $v;
$this->mDataLoaded = false;
}
function getName() {
$this->loadFromDatabase();
if ( $this->mName === false ) {
$this->mName = wfGetIP();
}
return $this->mName;
}
function setName( $str ) {
$this->loadFromDatabase();
$this->mName = $str;
}
/**
* Return the title dbkey form of the name, for eg user pages.
* @return string
* @public
*/
function getTitleKey() {
return str_replace( ' ', '_', $this->getName() );
}
function getNewtalk() {
$this->loadFromDatabase();
# Load the newtalk status if it is unloaded (mNewtalk=-1)
if( $this->mNewtalk === -1 ) {
$this->mNewtalk = false; # reset talk page status
# Check memcached separately for anons, who have no
# entire User object stored in there.
if( !$this->mId ) {
global $wgDBname, $wgMemc;
$key = "$wgDBname:newtalk:ip:" . $this->getName();
$newtalk = $wgMemc->get( $key );
if( is_integer( $newtalk ) ) {
$this->mNewtalk = (bool)$newtalk;
} else {
$this->mNewtalk = $this->checkNewtalk( 'user_ip', $this->getName() );
$wgMemc->set( $key, $this->mNewtalk, time() ); // + 1800 );
}
} else {
$this->mNewtalk = $this->checkNewtalk( 'user_id', $this->mId );
}
}
return (bool)$this->mNewtalk;
}
/**
* Return the talk page(s) this user has new messages on.
*/
function getNewMessageLinks() {
global $wgDBname;
$talks = array();
if (!wfRunHooks('UserRetrieveNewTalks', array(&$this, &$talks)))
return $talks;
if (!$this->getNewtalk())
return array();
$up = $this->getUserPage();
$utp = $up->getTalkPage();
return array(array("wiki" => $wgDBname, "link" => $utp->getLocalURL()));
}
/**
* Perform a user_newtalk check on current slaves; if the memcached data
* is funky we don't want newtalk state to get stuck on save, as that's
* damn annoying.
*
* @param string $field
* @param mixed $id
* @return bool
* @private
*/
function checkNewtalk( $field, $id ) {
$fname = 'User::checkNewtalk';
$dbr =& wfGetDB( DB_SLAVE );
$ok = $dbr->selectField( 'user_newtalk', $field,
array( $field => $id ), $fname );
return $ok !== false;
}
/**
* Add or update the
* @param string $field
* @param mixed $id
* @private
*/
function updateNewtalk( $field, $id ) {
$fname = 'User::updateNewtalk';
if( $this->checkNewtalk( $field, $id ) ) {
wfDebug( "$fname already set ($field, $id), ignoring\n" );
return false;
}
$dbw =& wfGetDB( DB_MASTER );
$dbw->insert( 'user_newtalk',
array( $field => $id ),
$fname,
'IGNORE' );
wfDebug( "$fname: set on ($field, $id)\n" );
return true;
}
/**
* Clear the new messages flag for the given user
* @param string $field
* @param mixed $id
* @private
*/
function deleteNewtalk( $field, $id ) {
$fname = 'User::deleteNewtalk';
if( !$this->checkNewtalk( $field, $id ) ) {
wfDebug( "$fname: already gone ($field, $id), ignoring\n" );
return false;
}
$dbw =& wfGetDB( DB_MASTER );
$dbw->delete( 'user_newtalk',
array( $field => $id ),
$fname );
wfDebug( "$fname: killed on ($field, $id)\n" );
return true;
}
/**
* Update the 'You have new messages!' status.
* @param bool $val
*/
function setNewtalk( $val ) {
if( wfReadOnly() ) {
return;
}
$this->loadFromDatabase();
$this->mNewtalk = $val;
$fname = 'User::setNewtalk';
if( $this->isAnon() ) {
$field = 'user_ip';
$id = $this->getName();
} else {
$field = 'user_id';
$id = $this->getId();
}
if( $val ) {
$changed = $this->updateNewtalk( $field, $id );
} else {
$changed = $this->deleteNewtalk( $field, $id );
}
if( $changed ) {
if( $this->isAnon() ) {
// Anons have a separate memcached space, since
// user records aren't kept for them.
global $wgDBname, $wgMemc;
$key = "$wgDBname:newtalk:ip:$val";
$wgMemc->set( $key, $val ? 1 : 0 );
} else {
if( $val ) {
// Make sure the user page is watched, so a notification
// will be sent out if enabled.
$this->addWatch( $this->getTalkPage() );
}
}
$this->invalidateCache();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?