Index: includes/User.php =================================================================== --- includes/User.php (revision 58311) +++ includes/User.php (working copy) @@ -3576,7 +3576,7 @@ protected function loadOptions() { $this->load(); - if ( $this->mOptionsLoaded || !$this->getId() ) + if ( $this->mOptionsLoaded ) return; $this->mOptions = self::getDefaultOptions(); @@ -3588,20 +3588,11 @@ $this->mOptions[$key] = $value; } } else { - wfDebug( "Loading options for user " . $this->getId() . " from database.\n" ); - // Load from database - $dbr = wfGetDB( DB_SLAVE ); - - $res = $dbr->select( - 'user_properties', - '*', - array( 'up_user' => $this->getId() ), - __METHOD__ - ); - - while( $row = $dbr->fetchObject( $res ) ) { - $this->mOptionOverrides[$row->up_property] = $row->up_value; - $this->mOptions[$row->up_property] = $row->up_value; + $this->mOptionOverrides = array(); + if ( $this->getId() ) { + $this->loadOptionsFromDatabase(); + } else { + $this->loadOptionsFromCookie(); } } @@ -3610,23 +3601,73 @@ wfRunHooks( 'UserLoadOptions', array( $this, &$this->mOptions ) ); } + protected function loadOptionsFromDatabase() { + wfDebug( "Loading options for user ".$this->getId()." from database.\n" ); + // Load from database + $dbr = wfGetDB( DB_SLAVE ); + + $res = $dbr->select( + 'user_properties', + '*', + array('up_user' => $this->getId()), + __METHOD__ + ); + + while( $row = $dbr->fetchObject( $res ) ) { + $this->mOptionOverrides[$row->up_property] = $row->up_value; + $this->mOptions[$row->up_property] = $row->up_value; + } + } + + protected function loadOptionsFromCookie() { + global $wgCookiePrefix; + $cookie = $_COOKIE[$wgCookiePrefix."Options"]; + + $overrides = json_decode($cookie, true); // Load assoc array from cookie + + foreach( $overrides as $key => $value ) { + $this->mOptions[$key] = $value; + $this->mOptionOverrides[$key] = $value; + } + } + protected function saveOptions() { global $wgAllowPrefChange; - $extuser = ExternalUser::newFromUser( $this ); - $this->loadOptions(); - $dbw = wfGetDB( DB_MASTER ); - $insert_rows = array(); - $saveOptions = $this->mOptions; + $extuser = ExternalUser::newFromUser( $this ); + foreach( $saveOptions as $key => $value ) { + if ( $extuser && isset( $wgAllowPrefChange[$key] ) ) { + switch ( $wgAllowPrefChange[$key] ) { + case 'local': + case 'message': + break; + case 'semiglobal': + case 'global': + $extuser->setPref( $key, $value ); + } + } + } + // Allow hooks to abort, for instance to save to a global profile. // Reset options to default state before saving. if( !wfRunHooks( 'UserSaveOptions', array( $this, &$saveOptions ) ) ) return; + if ( $this->getId() ) { + $this->saveOptionsToDatabase( $saveOptions ); + } else { + $this->saveOptionsToCookie( $saveOptions ); + } + } + + protected function saveOptionsToDatabase( $saveOptions ) { + $dbw = wfGetDB( DB_MASTER ); + $insert_rows = array(); + foreach( $saveOptions as $key => $value ) { # Don't bother storing default values if ( ( is_null( self::getDefaultOption( $key ) ) && @@ -3638,16 +3679,6 @@ 'up_value' => $value, ); } - if ( $extuser && isset( $wgAllowPrefChange[$key] ) ) { - switch ( $wgAllowPrefChange[$key] ) { - case 'local': - case 'message': - break; - case 'semiglobal': - case 'global': - $extuser->setPref( $key, $value ); - } - } } $dbw->begin(); @@ -3656,6 +3687,12 @@ $dbw->commit(); } + protected function saveOptionsToCookie( $saveOptions ) { + global $wgRequest; + + $data = json_encode( $saveOptions ); + $wgRequest->response()->setCookie( 'Options', $data, 86400 * 360 ); + } /** * Provide an array of HTML 5 attributes to put on an input element * intended for the user to enter a new password. This may include