X-Git-Url: http://git.cyclocoop.org/?a=blobdiff_plain;f=includes%2FUser.php;h=62e35e81667159b7ed97834526a543ab29df19d5;hb=3b57bd5fcae51d924a65116d6ec07475cade4bac;hp=b5fb1ff7c0b6fef8bc040dfc64d6de89f8021da4;hpb=7e3d257fc5b952740daaa5a80180930967f21304;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/User.php b/includes/User.php index b5fb1ff7c0..62e35e8166 100644 --- a/includes/User.php +++ b/includes/User.php @@ -56,7 +56,7 @@ class PasswordError extends MWException { * 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. @@ -149,6 +149,7 @@ class User { 'nominornewtalk', 'noratelimit', 'override-export-depth', + 'pagelang', 'passwordreset', 'patrol', 'patrolmarks', @@ -891,38 +892,6 @@ class User { 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. @@ -1169,9 +1138,10 @@ class User { * 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 ); @@ -1186,7 +1156,10 @@ class User { '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 ) ); @@ -2773,6 +2746,8 @@ class User { } } + wfRunHooks( 'UserResetAllOptions', array( $this, &$newOptions, $this->mOptions, $resetKinds ) ); + $this->mOptions = $newOptions; $this->mOptionsLoaded = true; } @@ -2941,7 +2916,7 @@ class User { 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 ); @@ -3605,17 +3580,25 @@ class User { 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; } } @@ -4795,13 +4778,13 @@ class User { } $userId = $this->getId(); - $insert_rows = array(); + + $insert_rows = array(); // all the new preference rows foreach ( $saveOptions as $key => $value ) { // Don't bother storing default values $defaultOption = self::getDefaultOption( $key ); - if ( ( is_null( $defaultOption ) && - !( $value === false || is_null( $value ) ) ) || - $value != $defaultOption + if ( ( $defaultOption === null && $value !== false && $value !== null ) + || $value != $defaultOption ) { $insert_rows[] = array( 'up_user' => $userId, @@ -4812,14 +4795,22 @@ class User { } $dbw = wfGetDB( DB_MASTER ); - // Find and delete any prior preference rows... + $res = $dbw->select( 'user_properties', - array( 'up_property' ), array( 'up_user' => $userId ), __METHOD__ ); - $priorKeys = array(); + array( 'up_property', 'up_value' ), array( 'up_user' => $userId ), __METHOD__ ); + + // Find prior rows that need to be removed or updated. These rows will + // all be deleted (the later so that INSERT IGNORE applies the new values). + $keysDelete = array(); foreach ( $res as $row ) { - $priorKeys[] = $row->up_property; + if ( !isset( $saveOptions[$row->up_property] ) + || strcmp( $saveOptions[$row->up_property], $row->up_value ) != 0 + ) { + $keysDelete[] = $row->up_property; + } } - if ( count( $priorKeys ) ) { + + if ( count( $keysDelete ) ) { // Do the DELETE by PRIMARY KEY for prior rows. // In the past a very large portion of calls to this function are for setting // 'rememberpassword' for new accounts (a preference that has since been removed). @@ -4828,7 +4819,7 @@ class User { // updates would pile up on each other as they are for higher (newer) user IDs. // It might not be necessary these days, but it shouldn't hurt either. $dbw->delete( 'user_properties', - array( 'up_user' => $userId, 'up_property' => $priorKeys ), __METHOD__ ); + array( 'up_user' => $userId, 'up_property' => $keysDelete ), __METHOD__ ); } // Insert the new preference rows $dbw->insert( 'user_properties', $insert_rows, __METHOD__, array( 'IGNORE' ) );