* of the database.
*/
class User {
+ /**
+ * Global constants made accessible as class constants so that autoloader
+ * magic can be used.
+ */
+ const USER_TOKEN_LENGTH = USER_TOKEN_LENGTH;
+ const MW_USER_VERSION = MW_USER_VERSION;
+ const EDIT_TOKEN_SUFFIX = EDIT_TOKEN_SUFFIX;
/**
* \type{\arrayof{\string}} List of member variables which are saved to the
* @see newFromSession()
* @see newFromRow()
*/
- function User() {
+ function __construct() {
$this->clearInstanceCache( 'defaults' );
}
}
if ( !$data ) {
- wfDebug( "Cache miss for user {$this->mId}\n" );
+ wfDebug( "User: cache miss for user {$this->mId}\n" );
# Load from DB
if ( !$this->loadFromDatabase() ) {
# Can't load from ID, user is anonymous
}
$this->saveToCache();
} else {
- wfDebug( "Got user {$this->mId} from cache\n" );
+ wfDebug( "User: got user {$this->mId} from cache\n" );
# Restore from cache
foreach ( self::$mCacheVars as $name ) {
$this->$name = $data[$name];
* User::getCanonicalName(), except that true is accepted as an alias
* for 'valid', for BC.
*
- * @return \type{User} The User object, or false if the username is invalid
+ * @return User The User object, or false if the username is invalid
* (e.g. if it contains illegal characters or is an IP address). If the
* username is not present in the database, the result will be a user object
* with a name, zero user ID and default settings.
* @return mixed: true on success, string of error message on failure
*/
function getPasswordValidity( $password ) {
- global $wgMinimalPasswordLength, $wgContLang;
+ global $wgMinimalPasswordLength, $wgWeakPasswords, $wgContLang;
$result = false; //init $result to false for the internal checks
if( !wfRunHooks( 'isValidPassword', array( $password, &$result, $this ) ) )
return $result;
+ $lcPassword = $wgContLang->lc( $password );
+
if ( $result === false ) {
if( strlen( $password ) < $wgMinimalPasswordLength ) {
return 'passwordtooshort';
- } elseif ( $wgContLang->lc( $password ) == $wgContLang->lc( $this->mName ) ) {
+ } elseif ( $lcPassword == $wgContLang->lc( $this->mName ) ) {
return 'password-name-match';
+ } elseif ( in_array( $lcPassword, $wgWeakPasswords ) ) {
+ return 'password-too-weak';
} else {
//it seems weird returning true here, but this is because of the
//initialization of $result to false above. If the hook is never run or it
if( !wfRunHooks( 'isValidEmailAddr', array( $addr, &$result ) ) ) {
return $result;
}
+ $rfc5322_atext = "a-z0-9!#$%&'*+-\/=?^_`{|}—~" ;
+ $rfc1034_ldh_str = "a-z0-9-" ;
+
+ $HTML5_email_regexp = "/
+ ^ # start of string
+ [$rfc5322_atext\\.]+ # user part which is liberal :p
+ @ # 'apostrophe'
+ [$rfc1034_ldh_str]+ # First domain part
+ (\\.[$rfc1034_ldh_str]+)+ # Following part prefixed with a dot
+ $ # End of string
+ /ix" ; // case Insensitive, eXtended
- return strpos( $addr, '@' ) !== false;
+ return (bool) preg_match( $HTML5_email_regexp, $addr );
}
/**
}
# Reject various classes of invalid names
- $name = $t->getText();
global $wgAuth;
$name = $wgAuth->getCanonicalName( $t->getText() );
return false;
}
- $passwordCorrect = FALSE;
$this->mId = $sId;
if ( !$this->loadFromId() ) {
# Not a valid ID, loadFromId has switched the object to anon for us
if ( ( $sName == $this->mName ) && $passwordCorrect ) {
$_SESSION['wsToken'] = $this->mToken;
- wfDebug( "Logged in from $from\n" );
+ wfDebug( "User: logged in from $from\n" );
return true;
} else {
# Invalid credentials
- wfDebug( "Can't log in from $from, invalid credentials\n" );
+ wfDebug( "User: can't log in from $from, invalid credentials\n" );
$this->loadDefaults();
return false;
}
array( 'ug_user' => $this->mId ),
__METHOD__ );
$this->mGroups = array();
- while( $row = $dbr->fetchObject( $res ) ) {
+ foreach ( $res as $row ) {
$this->mGroups[] = $row->ug_group;
}
}
/**
* default language setting
*/
- $variant = $wgContLang->getPreferredVariant( false );
+ $variant = $wgContLang->getDefaultVariant();
$defOpt['variant'] = $variant;
$defOpt['language'] = $variant;
foreach( SearchEngine::searchableNamespaces() as $nsnum => $nsname ) {
wfProfileIn( __METHOD__ );
$found = false;
- $host = '';
// FIXME: IPv6 ??? (http://bugs.php.net/bug.php?id=33170)
if( IP::isIPv4( $ip ) ) {
# Reverse IP, bug 21255
/**
* Get the user's ID.
- * @return \int The user's ID; 0 if the user is anonymous or nonexistent
+ * @return Integer The user's ID; 0 if the user is anonymous or nonexistent
*/
function getId() {
if( $this->mId === null and $this->mName !== null
if ( $oname == 'skin' ) {
# Clear cached skin, so the new one displays immediately in Special:Preferences
- unset( $this->mSkin );
+ $this->mSkin = null;
}
// Explicitly NULL values should refer to defaults
/**
* Check if user is allowed to access a feature / make an action
* @param $action \string action to be checked
- * @return \bool True if action is allowed, else false
+ * @return Boolean: True if action is allowed, else false
*/
function isAllowed( $action = '' ) {
- if ( $action === '' )
+ if ( $action === '' ) {
return true; // In the spirit of DWIM
+ }
# Patrolling may not be enabled
if( $action === 'patrol' || $action === 'autopatrol' ) {
global $wgUseRCPatrol, $wgUseNPPatrol;
/**
* Check whether to enable recent changes patrol features for this user
- * @return \bool True or false
+ * @return Boolean: True or false
*/
public function useRCPatrol() {
global $wgUseRCPatrol;
* @return Skin The current skin
* @todo FIXME : need to check the old failback system [AV]
*/
- function &getSkin( $t = null ) {
- if ( !isset( $this->mSkin ) ) {
- wfProfileIn( __METHOD__ );
-
- global $wgHiddenPrefs;
- if( !in_array( 'skin', $wgHiddenPrefs ) ) {
- # get the user skin
- global $wgRequest;
- $userSkin = $this->getOption( 'skin' );
- $userSkin = $wgRequest->getVal( 'useskin', $userSkin );
- } else {
- # if we're not allowing users to override, then use the default
- global $wgDefaultSkin;
- $userSkin = $wgDefaultSkin;
+ function getSkin( $t = null ) {
+ if ( $t ) {
+ $skin = $this->createSkinObject();
+ $skin->setTitle( $t );
+ return $skin;
+ } else {
+ if ( !$this->mSkin ) {
+ $this->mSkin = $this->createSkinObject();
}
- $this->mSkin = Skin::newFromKey( $userSkin );
- wfProfileOut( __METHOD__ );
- }
- if( $t || !$this->mSkin->getTitle() ) {
- if ( !$t ) {
+ if ( !$this->mSkin->getTitle() ) {
global $wgOut;
$t = $wgOut->getTitle();
+ $this->mSkin->setTitle($t);
}
- $this->mSkin->setTitle( $t );
+
+ return $this->mSkin;
+ }
+ }
+
+ // Creates a Skin object, for getSkin()
+ private function createSkinObject() {
+ wfProfileIn( __METHOD__ );
+
+ global $wgHiddenPrefs;
+ if( !in_array( 'skin', $wgHiddenPrefs ) ) {
+ global $wgRequest;
+ # get the user skin
+ $userSkin = $this->getOption( 'skin' );
+ $userSkin = $wgRequest->getVal( 'useskin', $userSkin );
+ } else {
+ # if we're not allowing users to override, then use the default
+ global $wgDefaultSkin;
+ $userSkin = $wgDefaultSkin;
}
- return $this->mSkin;
+
+ $skin = Skin::newFromKey( $userSkin );
+ wfProfileOut( __METHOD__ );
+
+ return $skin;
}
/**
$this->mOptionsLoaded = true;
$this->mOptionOverrides = array();
- $this->mOptions = array();
+ // If an option is not set in $str, use the default value
+ $this->mOptions = self::getDefaultOptions();
+
$a = explode( "\n", $str );
foreach ( $a as $s ) {
$m = array();
}
$dbw = wfGetDB( DB_MASTER );
$seqVal = $dbw->nextSequenceValue( 'user_user_id_seq' );
+
$fields = array(
'user_id' => $seqVal,
'user_name' => $name,
'user_password' => $user->mPassword,
'user_newpassword' => $user->mNewpassword,
- 'user_newpass_time' => $dbw->timestamp( $user->mNewpassTime ),
+ 'user_newpass_time' => $dbw->timestampOrNull( $user->mNewpassTime ),
'user_email' => $user->mEmail,
'user_email_authenticated' => $dbw->timestampOrNull( $user->mEmailAuthenticated ),
'user_real_name' => $user->mRealName,
'user_name' => $this->mName,
'user_password' => $this->mPassword,
'user_newpassword' => $this->mNewpassword,
- 'user_newpass_time' => $dbw->timestamp( $this->mNewpassTime ),
+ 'user_newpass_time' => $dbw->timestampOrNull( $this->mNewpassTime ),
'user_email' => $this->mEmail,
'user_email_authenticated' => $dbw->timestampOrNull( $this->mEmailAuthenticated ),
'user_real_name' => $this->mRealName,
* which will give them a chance to modify this key based on their own
* settings.
*
+ * @deprecated use the ParserOptions object to get the relevant options
* @return \string Page rendering hash
*/
function getPageRenderingHash() {
if( $this->mHash ){
return $this->mHash;
}
+ wfDeprecated( __METHOD__ );
// stubthreshold is only included below for completeness,
// since it disables the parser cache, its value will always
/**
* Get whether the user is blocked from using Special:Emailuser.
- * @return \bool True if blocked
+ * @return Boolean: True if blocked
*/
function isBlockedFromEmailuser() {
$this->getBlockedStatus();
/**
* Get whether the user is allowed to create an account.
- * @return \bool True if allowed
+ * @return Boolean: True if allowed
*/
function isAllowedToCreateAccount() {
return $this->isAllowed( 'createaccount' ) && !$this->isBlockedFromCreateAccount();
/**
* Get this user's personal page title.
*
- * @return \type{Title} User's personal page title
+ * @return Title: User's personal page title
*/
function getUserPage() {
return Title::makeTitle( NS_USER, $this->getName() );
/**
* Get this user's talk page title.
*
- * @return \type{Title} User's talk page title
+ * @return Title: User's talk page title
*/
function getTalkPage() {
$title = $this->getUserPage();
/**
* Get the maximum valid user ID.
- * @return \int User ID
+ * @return Integer: User ID
* @static
*/
function getMaxID() {
static $res; // cache
- if ( isset( $res ) )
+ if ( isset( $res ) ) {
return $res;
- else {
+ } else {
$dbr = wfGetDB( DB_SLAVE );
return $res = $dbr->selectField( 'user', 'max(user_id)', false, __METHOD__ );
}
/**
* Determine whether the user is a newbie. Newbies are either
* anonymous IPs, or the most recently created accounts.
- * @return \bool True if the user is a newbie
+ * @return Boolean: True if the user is a newbie
*/
function isNewbie() {
return !$this->isAllowed( 'autoconfirmed' );
/**
* Check to see if the given clear-text password is one of the accepted passwords
- * @param $password \string user password.
- * @return \bool True if the given password is correct, otherwise False.
+ * @param $password String: user password.
+ * @return Boolean: True if the given password is correct, otherwise False.
*/
function checkPassword( $password ) {
global $wgAuth;
$this->load();
- // Even though we stop people from creating passwords that
- // are shorter than this, doesn't mean people wont be able
- // to. Certain authentication plugins do NOT want to save
- // domain passwords in a mysql database, so we should
- // check this (incase $wgAuth->strict() is false).
- if( !$this->isValidPassword( $password ) ) {
- return false;
- }
-
if( $wgAuth->authenticate( $this->getName(), $password ) ) {
return true;
} elseif( $wgAuth->strict() ) {
/**
* Check if the given clear-text password matches the temporary password
* sent by e-mail for password reset operations.
- * @return \bool True if matches, false otherwise
+ * @return Boolean: True if matches, false otherwise
*/
function checkTemporaryPassword( $plaintext ) {
global $wgNewPasswordExpiry;
*
* @param $val \string Input value to compare
* @param $salt \string Optional function-specific data for hashing
- * @return \bool Whether the token matches
+ * @return Boolean: Whether the token matches
*/
function matchEditToken( $val, $salt = '' ) {
$sessionToken = $this->editToken( $salt );
*
* @param $val \string Input value to compare
* @param $salt \string Optional function-specific data for hashing
- * @return \bool Whether the token matches
+ * @return Boolean: Whether the token matches
*/
function matchEditTokenNoSuffix( $val, $salt = '' ) {
$sessionToken = $this->editToken( $salt );
*/
function sendMail( $subject, $body, $from = null, $replyto = null ) {
if( is_null( $from ) ) {
- global $wgPasswordSender;
- $from = $wgPasswordSender;
+ global $wgPasswordSender, $wgPasswordSenderName;
+ $sender = new MailAddress( $wgPasswordSender, $wgPasswordSenderName );
+ } else {
+ $sender = new MailAddress( $from );
}
$to = new MailAddress( $this );
- $sender = new MailAddress( $from );
return UserMailer::send( $to, $sender, $subject, $body, $replyto );
}
/**
* Is this user allowed to send e-mails within limits of current
* site configuration?
- * @return \bool True if allowed
+ * @return Boolean: True if allowed
*/
function canSendEmail() {
global $wgEnableEmail, $wgEnableUserEmail;
/**
* Is this user allowed to receive e-mails within limits of current
* site configuration?
- * @return \bool True if allowed
+ * @return Boolean: True if allowed
*/
function canReceiveEmail() {
return $this->isEmailConfirmed() && !$this->getOption( 'disablemail' );
* confirmed their address by returning a code or using a password
* sent to the address from the wiki.
*
- * @return \bool True if confirmed
+ * @return Boolean: True if confirmed
*/
function isEmailConfirmed() {
global $wgEmailAuthentication;
/**
* Check whether there is an outstanding request for e-mail confirmation.
- * @return \bool True if pending
+ * @return Boolean: True if pending
*/
function isEmailConfirmationPending() {
global $wgEmailAuthentication;
* @param $hash \string Password hash
* @param $password \string Plain-text password to compare
* @param $userId \string User ID for old-style password salt
- * @return \bool
+ * @return Boolean:
*/
static function comparePasswords( $hash, $password, $userId = false ) {
$type = substr( $hash, 0, 3 );
// Maybe load from the object
if ( !is_null( $this->mOptionOverrides ) ) {
- wfDebug( "Loading options for user " . $this->getId() . " from override cache.\n" );
+ wfDebug( "User: loading options for user " . $this->getId() . " from override cache.\n" );
foreach( $this->mOptionOverrides as $key => $value ) {
$this->mOptions[$key] = $value;
}
} else {
- wfDebug( "Loading options for user " . $this->getId() . " from database.\n" );
+ wfDebug( "User: loading options for user " . $this->getId() . " from database.\n" );
// Load from database
$dbr = wfGetDB( DB_SLAVE );
__METHOD__
);
- while( $row = $dbr->fetchObject( $res ) ) {
+ foreach ( $res as $row ) {
$this->mOptionOverrides[$row->up_property] = $row->up_value;
$this->mOptions[$row->up_property] = $row->up_value;
}