* for rendering normal pages are set in the cookie to minimize use
* of the database.
*/
-class User {
+class User implements IDBAccessObject {
/**
* Global constants made accessible as class constants so that autoloader
* magic can be used.
'nominornewtalk',
'noratelimit',
'override-export-depth',
+ 'pagelang',
'passwordreset',
'patrol',
'patrolmarks',
return $this->mPasswordExpires;
}
- /**
- * Does a string look like an e-mail address?
- *
- * This validates an email address using an HTML5 specification found at:
- * http://www.whatwg.org/html/states-of-the-type-attribute.html#valid-e-mail-address
- * Which as of 2011-01-24 says:
- *
- * A valid e-mail address is a string that matches the ABNF production
- * 1*( atext / "." ) "@" ldh-str *( "." ldh-str ) where atext is defined
- * in RFC 5322 section 3.2.3, and ldh-str is defined in RFC 1034 section
- * 3.5.
- *
- * This function is an implementation of the specification as requested in
- * bug 22449.
- *
- * Client-side forms will use the same standard validation rules via JS or
- * HTML 5 validation; additional restrictions can be enforced server-side
- * by extensions via the 'isValidEmailAddr' hook.
- *
- * Note that this validation doesn't 100% match RFC 2822, but is believed
- * to be liberal enough for wide use. Some invalid addresses will still
- * pass validation here.
- *
- * @param string $addr E-mail address
- * @return bool
- * @deprecated since 1.18 call Sanitizer::isValidEmail() directly
- */
- public static function isValidEmailAddr( $addr ) {
- wfDeprecated( __METHOD__, '1.18' );
- return Sanitizer::validateEmail( $addr );
- }
-
/**
* Given unvalidated user input, return a canonical username, or false if
* the username is invalid.
* Load user and user_group data from the database.
* $this->mId must be set, this is how the user is identified.
*
+ * @param integer $flags Supports User::READ_LOCKING
* @return bool True if the user exists, false if the user is anonymous
*/
- public function loadFromDatabase() {
+ public function loadFromDatabase( $flags = 0 ) {
// Paranoia
$this->mId = intval( $this->mId );
'user',
self::selectFields(),
array( 'user_id' => $this->mId ),
- __METHOD__
+ __METHOD__,
+ ( $flags & self::READ_LOCKING == self::READ_LOCKING )
+ ? array( 'LOCK IN SHARE MODE' )
+ : array()
);
wfRunHooks( 'UserLoadFromDatabase', array( $this, &$s ) );
}
}
+ wfRunHooks( 'UserResetAllOptions', array( $this, &$newOptions, $this->mOptions, $resetKinds ) );
+
$this->mOptions = $newOptions;
$this->mOptionsLoaded = true;
}
return null;
}
- if ( !isset( $this->mEditCount ) ) {
+ if ( $this->mEditCount === null ) {
/* Populate the count, if it has not been populated yet */
wfProfileIn( __METHOD__ );
$dbr = wfGetDB( DB_SLAVE );
array( 'IGNORE' )
);
if ( !$dbw->affectedRows() ) {
- if ( !$inWrite ) {
- // XXX: Get out of REPEATABLE-READ so the SELECT below works.
- // Often this case happens early in views before any writes.
- // This shows up at least with CentralAuth.
+ // The queries below cannot happen in the same REPEATABLE-READ snapshot.
+ // Handle this by COMMIT, if possible, or by LOCK IN SHARE MODE otherwise.
+ if ( $inWrite ) {
+ // Can't commit due to pending writes that may need atomicity.
+ // This may cause some lock contention unlike the case below.
+ $options = array( 'LOCK IN SHARE MODE' );
+ $flags = self::READ_LOCKING;
+ } else {
+ // Often, this case happens early in views before any writes when
+ // using CentralAuth. It's should be OK to commit and break the snapshot.
$dbw->commit( __METHOD__, 'flush' );
+ $options = array();
+ $flags = 0;
}
$this->mId = $dbw->selectField( 'user', 'user_id',
- array( 'user_name' => $this->mName ), __METHOD__ );
+ array( 'user_name' => $this->mName ), __METHOD__, $options );
$loaded = false;
if ( $this->mId ) {
- if ( $this->loadFromDatabase() ) {
+ if ( $this->loadFromDatabase( $flags ) ) {
$loaded = true;
}
}