X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FUser.php;h=a38f60c178b07c6dc68afb6e20cbc814a0b79f62;hb=5c2b2730ff78e9f1ecac759a56470ce6eba859ef;hp=e1dc80eb37b43c2d02c779387f6fa18afebdc4ae;hpb=1412a6885c0c7caf7e4c2895b6002ff09e0e8fb7;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/User.php b/includes/User.php index e1dc80eb37..a38f60c178 100644 --- a/includes/User.php +++ b/includes/User.php @@ -1,64 +1,123 @@ -loadDefaults(); } - # Static factory method - # - function newFromName( $name ) - { + /** + * Static factory method + * @static + * @param string $name Username, validated by Title:newFromText() + */ + function newFromName( $name ) { $u = new User(); # Clean up name according to title rules $t = Title::newFromText( $name ); - $u->setName( $t->getText() ); - return $u; + if( is_null( $t ) ) { + return NULL; + } else { + $u->setName( $t->getText() ); + return $u; + } } - /* static */ function whoIs( $id ) - { - return wfGetSQL( "user", "user_name", "user_id=$id" ); - } + /** + * Get username given an id. + * @param integer $id Database user id + * @return string Nickname of a user + * @static + */ + function whoIs( $id ) { + $dbr =& wfGetDB( DB_SLAVE ); + return $dbr->selectField( 'user', 'user_name', array( 'user_id' => $id ) ); + } + + /** + * Get real username given an id. + * @param integer $id Database user id + * @return string Realname of a user + * @static + */ + function whoIsReal( $id ) { + $dbr =& wfGetDB( DB_SLAVE ); + return $dbr->selectField( 'user', 'user_real_name', array( 'user_id' => $id ) ); + } + + /** + * Get database id given a user name + * @param string $name Nickname of a user + * @return integer|null Database user id (null: if non existent + * @static + */ + function idFromName( $name ) { + $fname = "User::idFromName"; - /* static */ function idFromName( $name ) - { $nt = Title::newFromText( $name ); - $sql = "SELECT user_id FROM user WHERE user_name='" . - wfStrencode( $nt->getText() ) . "'"; - $res = wfQuery( $sql, "User::idFromName" ); + if( is_null( $nt ) ) { + # Illegal name + return null; + } + $dbr =& wfGetDB( DB_SLAVE ); + $s = $dbr->selectRow( 'user', array( 'user_id' ), array( 'user_name' => $nt->getText() ), $fname ); - if ( 0 == wfNumRows( $res ) ) { return 0; } - else { - $s = wfFetchObject( $res ); + if ( $s === false ) { + return 0; + } else { return $s->user_id; } } - # does the string match an anonymous user IP address? - /* static */ function isIP( $name ) { + /** + * does the string match an anonymous user IP address? + * @param string $name Nickname of a user + * @static + */ + function isIP( $name ) { return preg_match("/^\d{1,3}\.\d{1,3}.\d{1,3}\.\d{1,3}$/",$name); - } - /* static */ function randomPassword() - { - $pwchars = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz"; + /** + * probably return a random password + * @return string probably a random password + * @static + * @todo Check what is doing really [AV] + */ + function randomPassword() { + $pwchars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz'; $l = strlen( $pwchars ) - 1; - wfSeedRandom(); $np = $pwchars{mt_rand( 0, $l )} . $pwchars{mt_rand( 0, $l )} . $pwchars{mt_rand( 0, $l )} . chr( mt_rand(48, 57) ) . $pwchars{mt_rand( 0, $l )} . $pwchars{mt_rand( 0, $l )} . @@ -66,91 +125,158 @@ class User { return $np; } - function loadDefaults() - { - global $wgLang ; + /** + * Set properties to default + * Used at construction. It will load per language default settings only + * if we have an available language object. + */ + function loadDefaults() { + global $wgLang, $wgIP; global $wgNamespacesToBeSearchedDefault; $this->mId = $this->mNewtalk = 0; - $this->mName = getenv( "REMOTE_ADDR" ); - $this->mEmail = ""; - $this->mPassword = $this->mNewpassword = ""; + $this->mName = $wgIP; + $this->mRealName = $this->mEmail = ''; + $this->mPassword = $this->mNewpassword = ''; $this->mRights = array(); - $defOpt = $wgLang->getDefaultUserOptions() ; - foreach ( $defOpt as $oname => $val ) { - $this->mOptions[$oname] = $val; - } + // Getting user defaults only if we have an available language + if(isset($wgLang)) { $this->loadDefaultFromLanguage(); } + foreach ($wgNamespacesToBeSearchedDefault as $nsnum => $val) { - $this->mOptions["searchNs".$nsnum] = $val; + $this->mOptions['searchNs'.$nsnum] = $val; } unset( $this->mSkin ); $this->mDataLoaded = false; $this->mBlockedby = -1; # Unset $this->mTouched = '0'; # Allow any pages to be cached - $this->cookiePassword = ""; + $this->cookiePassword = ''; + $this->mHash = false; + } + + /** + * Used to load user options from a language. + * This is not in loadDefault() cause we sometime create user before having + * a language object. + */ + function loadDefaultFromLanguage(){ + global $wgLang; + $defOpt = $wgLang->getDefaultUserOptions() ; + foreach ( $defOpt as $oname => $val ) { + $this->mOptions[$oname] = $val; + } + /* so that new user will have a default + language variant set using info from the http header + */ + $this->setOption('variant', $wgLang->getPreferredVariant()); } - /* private */ function getBlockedStatus() - { + /** + * Get blocking information + * @access private + */ + function getBlockedStatus() { + global $wgIP, $wgBlockCache, $wgProxyList; + if ( -1 != $this->mBlockedby ) { return; } - $remaddr = getenv( "REMOTE_ADDR" ); - if ( 0 == $this->mId ) { - $sql = "SELECT ipb_by,ipb_reason FROM ipblocks WHERE " . - "ipb_address='$remaddr'"; - } else { - $sql = "SELECT ipb_by,ipb_reason FROM ipblocks WHERE " . - "(ipb_address='$remaddr' OR ipb_user={$this->mId})"; + $this->mBlockedby = 0; + + # User blocking + if ( $this->mId ) { + $block = new Block(); + if ( $block->load( $wgIP , $this->mId ) ) { + $this->mBlockedby = $block->mBy; + $this->mBlockreason = $block->mReason; + } } - $res = wfQuery( $sql, "User::getBlockedStatus" ); - if ( 0 == wfNumRows( $res ) ) { - $this->mBlockedby = 0; - return; + + # IP/range blocking + if ( !$this->mBlockedby ) { + $block = $wgBlockCache->get( $wgIP ); + if ( $block !== false ) { + $this->mBlockedby = $block->mBy; + $this->mBlockreason = $block->mReason; + } + } + + # Proxy blocking + if ( !$this->mBlockedby ) { + if ( array_key_exists( $wgIP, $wgProxyList ) ) { + $this->mBlockreason = wfMsg( 'proxyblockreason' ); + $this->mBlockedby = "Proxy blocker"; + } } - $s = wfFetchObject( $res ); - $this->mBlockedby = $s->ipb_by; - $this->mBlockreason = $s->ipb_reason; } - function isBlocked() - { + /** + * Check if user is blocked + * @return bool True if blocked, false otherwise + */ + function isBlocked() { $this->getBlockedStatus(); - if ( 0 == $this->mBlockedby ) { return false; } + if ( 0 === $this->mBlockedby ) { return false; } return true; } - + + /** + * 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; } - /* static */ function loadFromSession() - { - global $HTTP_COOKIE_VARS, $wsUserID, $wsUserName, $wsUserPassword; + /** + * Initialise php session + */ + function SetupSession() { + 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(); + } + + /** + * Read datas from session + * @static + */ + function loadFromSession() { global $wgMemc, $wgDBname; - if ( isset( $wsUserID ) ) { - if ( 0 != $wsUserID ) { - $sId = $wsUserID; + if ( isset( $_SESSION['wsUserID'] ) ) { + if ( 0 != $_SESSION['wsUserID'] ) { + $sId = $_SESSION['wsUserID']; } else { return new User(); } - } else if ( isset( $HTTP_COOKIE_VARS["wcUserID"] ) ) { - $sId = $HTTP_COOKIE_VARS["wcUserID"]; - $wsUserID = $sId; + } else if ( isset( $_COOKIE["{$wgDBname}UserID"] ) ) { + $sId = IntVal( $_COOKIE["{$wgDBname}UserID"] ); + $_SESSION['wsUserID'] = $sId; } else { return new User(); } - if ( isset( $wsUserName ) ) { - $sName = $wsUserName; - } else if ( isset( $HTTP_COOKIE_VARS["wcUserName"] ) ) { - $sName = $HTTP_COOKIE_VARS["wcUserName"]; - $wsUserName = $sName; + if ( isset( $_SESSION['wsUserName'] ) ) { + $sName = $_SESSION['wsUserName']; + } else if ( isset( $_COOKIE["{$wgDBname}UserName"] ) ) { + $sName = $_COOKIE["{$wgDBname}UserName"]; + $_SESSION['wsUserName'] = $sName; } else { return new User(); } @@ -166,12 +292,12 @@ class User { wfDebug( "User::loadFromSession() got from cache!\n" ); } - if ( isset( $wsUserPassword ) ) { - $passwordCorrect = $wsUserPassword == $user->mPassword; - } else if ( isset( $HTTP_COOKIE_VARS["wcUserPassword"] ) ) { - $user->mCookiePassword = $HTTP_COOKIE_VARS["wcUserPassword"]; - $wsUserPassword = $user->addSalt( $user->mCookiePassword ); - $passwordCorrect = $wsUserPassword == $user->mPassword; + if ( isset( $_SESSION['wsUserPassword'] ) ) { + $passwordCorrect = $_SESSION['wsUserPassword'] == $user->mPassword; + } else if ( isset( $_COOKIE["{$wgDBname}Password"] ) ) { + $user->mCookiePassword = $_COOKIE["{$wgDBname}Password"]; + $_SESSION['wsUserPassword'] = $user->addSalt( $user->mCookiePassword ); + $passwordCorrect = $_SESSION['wsUserPassword'] == $user->mPassword; } else { return new User(); # Can't log in from session } @@ -189,29 +315,38 @@ class User { return new User(); # Can't log in from session } - function loadFromDatabase() - { - if ( $this->mDataLoaded ) { return; } + /** + * Load a user from the database + */ + function loadFromDatabase() { + global $wgCommandLineMode; + $fname = "User::loadFromDatabase"; + if ( $this->mDataLoaded || $wgCommandLineMode ) { + return; + } + + # Paranoia + $this->mId = IntVal( $this->mId ); + # check in separate table if there are changes to the talk page $this->mNewtalk=0; # reset talk page status + $dbr =& wfGetDB( DB_SLAVE ); if($this->mId) { - $sql = "SELECT 1 FROM user_newtalk WHERE user_id={$this->mId}"; - $res = wfQuery ($sql, "User::loadFromDatabase" ); + $res = $dbr->select( 'user_newtalk', 1, array( 'user_id' => $this->mId ), $fname ); - if (wfNumRows($res)>0) { + if ( $dbr->numRows($res)>0 ) { $this->mNewtalk= 1; } - wfFreeResult( $res ); + $dbr->freeResult( $res ); } else { global $wgDBname, $wgMemc; $key = "$wgDBname:newtalk:ip:{$this->mName}"; $newtalk = $wgMemc->get( $key ); - if($newtalk === false) { - $sql = "SELECT 1 FROM user_newtalk WHERE user_ip='{$this->mName}'"; - $res = wfQuery ($sql, "User::loadFromDatabase" ); + if( ! is_integer( $newtalk ) ){ + $res = $dbr->select( 'user_newtalk', 1, array( 'user_ip' => $this->mName ), $fname ); - $this->mNewtalk = (wfNumRows($res)>0) ? 1 : 0; - wfFreeResult( $res ); + $this->mNewtalk = $dbr->numRows( $res ) > 0 ? 1 : 0; + $dbr->freeResult( $res ); $wgMemc->set( $key, $this->mNewtalk, time() ); // + 1800 ); } else { @@ -223,23 +358,23 @@ class User { return; } # the following stuff is for non-anonymous users only - $sql = "SELECT user_name,user_password,user_newpassword,user_email," . - "user_options,user_rights,user_touched FROM user WHERE user_id=" . - "{$this->mId}"; - $res = wfQuery( $sql, "User::loadFromDatabase" ); + $s = $dbr->selectRow( 'user', array( 'user_name','user_password','user_newpassword','user_email', + 'user_real_name','user_options','user_touched' ), + array( 'user_id' => $this->mId ), $fname ); - if ( wfNumRows( $res ) > 0 ) { - $s = wfFetchObject( $res ); + if ( $s !== false ) { $this->mName = $s->user_name; $this->mEmail = $s->user_email; + $this->mRealName = $s->user_real_name; $this->mPassword = $s->user_password; $this->mNewpassword = $s->user_newpassword; $this->decodeOptions( $s->user_options ); - $this->mRights = explode( ",", strtolower( $s->user_rights ) ); - $this->mTouched = $s->user_touched; + $this->mTouched = wfTimestamp(TS_MW,$s->user_touched); + $this->mRights = explode( ",", strtolower( + $dbr->selectField( 'user_rights', 'user_rights', array( 'user_id' => $this->mId ) ) + ) ); } - wfFreeResult( $res ); $this->mDataLoaded = true; } @@ -254,20 +389,17 @@ class User { return $this->mName; } - function setName( $str ) - { + function setName( $str ) { $this->loadFromDatabase(); $this->mName = $str; } - function getNewtalk() - { + function getNewtalk() { $this->loadFromDatabase(); return ( 0 != $this->mNewtalk ); } - function setNewtalk( $val ) - { + function setNewtalk( $val ) { $this->loadFromDatabase(); $this->mNewtalk = $val; $this->invalidateCache(); @@ -285,20 +417,13 @@ class User { return ($timestamp >= $this->mTouched); } - function getPassword() - { - $this->loadFromDatabase(); - return $this->mPassword; - } - - function getNewpassword() - { - $this->loadFromDatabase(); - return $this->mNewpassword; - } - - function addSalt( $p ) - { + /** + * Salt a password. + * Will only be salted if $wgPasswordSalt is true + * @param string Password. + * @return string Salted password or clear password. + */ + function addSalt( $p ) { global $wgPasswordSalt; if($wgPasswordSalt) return md5( "{$this->mId}-{$p}" ); @@ -306,165 +431,218 @@ class User { return $p; } - function encryptPassword( $p ) - { + /** + * Encrypt a password. + * It can eventuall salt a password @see User::addSalt() + * @param string $p clear Password. + * @param string Encrypted password. + */ + function encryptPassword( $p ) { return $this->addSalt( md5( $p ) ); } - function setPassword( $str ) - { + function setPassword( $str ) { $this->loadFromDatabase(); $this->setCookiePassword( $str ); $this->mPassword = $this->encryptPassword( $str ); - $this->mNewpassword = ""; + $this->mNewpassword = ''; } - function setCookiePassword( $str ) - { + function setCookiePassword( $str ) { $this->loadFromDatabase(); $this->mCookiePassword = md5( $str ); } - function setNewpassword( $str ) - { + function setNewpassword( $str ) { $this->loadFromDatabase(); $this->mNewpassword = $this->encryptPassword( $str ); } - function getEmail() - { + function getEmail() { $this->loadFromDatabase(); return $this->mEmail; } - function setEmail( $str ) - { + function setEmail( $str ) { $this->loadFromDatabase(); $this->mEmail = $str; } - function getOption( $oname ) - { + function getRealName() { + $this->loadFromDatabase(); + return $this->mRealName; + } + + function setRealName( $str ) { + $this->loadFromDatabase(); + $this->mRealName = $str; + } + + function getOption( $oname ) { $this->loadFromDatabase(); if ( array_key_exists( $oname, $this->mOptions ) ) { return $this->mOptions[$oname]; } else { - return ""; + return ''; } } - function setOption( $oname, $val ) - { + function setOption( $oname, $val ) { $this->loadFromDatabase(); + if ( $oname == 'skin' ) { + # Clear cached skin, so the new one displays immediately in Special:Preferences + unset( $this->mSkin ); + } $this->mOptions[$oname] = $val; $this->invalidateCache(); } - function getRights() - { + function getRights() { $this->loadFromDatabase(); return $this->mRights; } - function addRight( $rname ) - { + function addRight( $rname ) { $this->loadFromDatabase(); array_push( $this->mRights, $rname ); $this->invalidateCache(); } - function isSysop() - { + function isSysop() { $this->loadFromDatabase(); if ( 0 == $this->mId ) { return false; } - return in_array( "sysop", $this->mRights ); + return in_array( 'sysop', $this->mRights ); } - function isDeveloper() - { + function isDeveloper() { $this->loadFromDatabase(); if ( 0 == $this->mId ) { return false; } - return in_array( "developer", $this->mRights ); + return in_array( 'developer', $this->mRights ); } - function isBot() - { + function isBureaucrat() { $this->loadFromDatabase(); if ( 0 == $this->mId ) { return false; } - return in_array( "bot", $this->mRights ); + return in_array( 'bureaucrat', $this->mRights ); } - function &getSkin() - { + /** + * Whether the user is a bot + */ + function isBot() { + $this->loadFromDatabase(); + + # Why was this here? I need a UID=0 conversion script [TS] + # if ( 0 == $this->mId ) { return false; } + + return in_array( 'bot', $this->mRights ); + } + + /** + * Load a skin if it doesn't exist or return it + * @todo FIXME : need to check the old failback system [AV] + */ + function &getSkin() { + global $IP, $wgUsePHPTal; if ( ! isset( $this->mSkin ) ) { + # get all skin names available $skinNames = Skin::getSkinNames(); - $s = $this->getOption( "skin" ); - if ( "" == $s ) { $s = 0; } + # get the user skin + $userSkin = $this->getOption( 'skin' ); + if ( $userSkin == '' ) { $userSkin = 'standard'; } + + if ( !isset( $skinNames[$userSkin] ) ) { + # in case the user skin could not be found find a replacement + $fallback = array( + 0 => 'Standard', + 1 => 'Nostalgia', + 2 => 'CologneBlue'); + # if phptal is enabled we should have monobook skin that + # superseed the good old SkinStandard. + if ( isset( $skinNames['monobook'] ) ) { + $fallback[0] = 'MonoBook'; + } + + if(is_numeric($userSkin) && isset( $fallback[$userSkin]) ){ + $sn = $fallback[$userSkin]; + } else { + $sn = 'Standard'; + } + } else { + # The user skin is available + $sn = $skinNames[$userSkin]; + } - if ( $s >= count( $skinNames ) ) { $sn = "SkinStandard"; } - else $sn = "Skin" . $skinNames[$s]; + # Grab the skin class and initialise it. Each skin checks for PHPTal + # and will not load if it's not enabled. + require_once( $IP.'/skins/'.$sn.'.php' ); + + # Check if we got if not failback to default skin + $sn = 'Skin'.$sn; + if(!class_exists($sn)) { + # FIXME : should we print an error message instead of loading + # standard skin ? Let's die for now. [AV] + die("Class $sn doesn't exist in $IP/skins/$sn.php"); + $sn = 'SkinStandard'; + require_once( $IP.'/skins/Standard.php' ); + } $this->mSkin = new $sn; } return $this->mSkin; } - function isWatched( $title ) - { - # Note - $title should be a Title _object_ - # Pages and their talk pages are considered equivalent for watching; - # remember that talk namespaces are numbered as page namespace+1. - if( $this->mId ) { - $sql = "SELECT 1 FROM watchlist - WHERE wl_user={$this->mId} AND - wl_namespace = " . ($title->getNamespace() & ~1) . " AND - wl_title='" . wfStrencode( $title->getDBkey() ) . "'"; - $res = wfQuery( $sql ); - return (wfNumRows( $res ) > 0); - } else { - return false; - } - } - - function addWatch( $title ) - { - if( $this->mId ) { - # REPLACE instead of INSERT because occasionally someone - # accidentally reloads a watch-add operation. - $sql = "REPLACE INTO watchlist (wl_user, wl_namespace,wl_title) - VALUES ({$this->mId}," . (($title->getNamespace() | 1) - 1) . - ",'" . wfStrencode( $title->getDBkey() ) . "')"; - wfQuery( $sql ); - $this->invalidateCache(); - } + /**#@+ + * @param string $title Article title to look at + */ + + /** + * Check watched status of an article + * @return bool True if article is watched + */ + function isWatched( $title ) { + $wl = WatchedItem::fromUserTitle( $this, $title ); + return $wl->isWatched(); + } + + /** + * Watch an article + */ + function addWatch( $title ) { + $wl = WatchedItem::fromUserTitle( $this, $title ); + $wl->addWatch(); + $this->invalidateCache(); } - function removeWatch( $title ) - { - if( $this->mId ) { - $sql = "DELETE FROM watchlist WHERE wl_user={$this->mId} AND - wl_namespace=" . (($title->getNamespace() | 1) - 1) . - " AND wl_title='" . wfStrencode( $title->getDBkey() ) . "'"; - wfQuery( $sql ); - $this->invalidateCache(); - } + /** + * Stop watching an article + */ + function removeWatch( $title ) { + $wl = WatchedItem::fromUserTitle( $this, $title ); + $wl->removeWatch(); + $this->invalidateCache(); } + /**#@-*/ - - /* private */ function encodeOptions() - { + /** + * @access private + * @return string Encoding options + */ + function encodeOptions() { $a = array(); foreach ( $this->mOptions as $oname => $oval ) { - array_push( $a, "{$oname}={$oval}" ); + array_push( $a, $oname.'='.$oval ); } $s = implode( "\n", $a ); - return wfStrencode( $s ); + return $s; } - /* private */ function decodeOptions( $str ) - { + /** + * @access private + */ + function decodeOptions( $str ) { $a = explode( "\n", $str ); foreach ( $a as $s ) { if ( preg_match( "/^(.[^=]*)=(.*)$/", $s, $m ) ) { @@ -473,141 +651,259 @@ class User { } } - function setCookies() - { - global $wsUserID, $wsUserName, $wsUserPassword; - global $wgCookieExpiration; + function setCookies() { + global $wgCookieExpiration, $wgCookiePath, $wgCookieDomain, $wgDBname; if ( 0 == $this->mId ) return; $this->loadFromDatabase(); $exp = time() + $wgCookieExpiration; - $wsUserID = $this->mId; - setcookie( "wcUserID", $this->mId, $exp, "/" ); + $_SESSION['wsUserID'] = $this->mId; + setcookie( $wgDBname.'UserID', $this->mId, $exp, $wgCookiePath, $wgCookieDomain ); - $wsUserName = $this->mName; - setcookie( "wcUserName", $this->mName, $exp, "/" ); + $_SESSION['wsUserName'] = $this->mName; + setcookie( $wgDBname.'UserName', $this->mName, $exp, $wgCookiePath, $wgCookieDomain ); - $wsUserPassword = $this->mPassword; - if ( 1 == $this->getOption( "rememberpassword" ) ) { - setcookie( "wcUserPassword", $this->mCookiePassword, $exp, "/" ); + $_SESSION['wsUserPassword'] = $this->mPassword; + if ( 1 == $this->getOption( 'rememberpassword' ) ) { + setcookie( $wgDBname.'Password', $this->mCookiePassword, $exp, $wgCookiePath, $wgCookieDomain ); } else { - setcookie( "wcUserPassword", "", time() - 3600 ); + setcookie( $wgDBname.'Password', '', time() - 3600 ); } } - function logout() - { - global $wsUserID; + /** + * Logout user + * It will clean the session cookie + */ + function logout() { + global $wgCookiePath, $wgCookieDomain, $wgDBname; $this->mId = 0; - $wsUserID = 0; + $_SESSION['wsUserID'] = 0; - setcookie( "wcUserID", "", time() - 3600 ); - setcookie( "wcUserPassword", "", time() - 3600 ); + setcookie( $wgDBname.'UserID', '', time() - 3600, $wgCookiePath, $wgCookieDomain ); + setcookie( $wgDBname.'Password', '', time() - 3600, $wgCookiePath, $wgCookieDomain ); } - function saveSettings() - { + /** + * Save object settings into database + */ + function saveSettings() { global $wgMemc, $wgDBname; + $fname = 'User::saveSettings'; + $dbw =& wfGetDB( DB_MASTER ); if ( ! $this->mNewtalk ) { + # Delete user_newtalk row if( $this->mId ) { - $sql="DELETE FROM user_newtalk WHERE user_id={$this->mId}"; - wfQuery ($sql,"User::saveSettings"); + $dbw->delete( 'user_newtalk', array( 'user_id' => $this->mId ), $fname ); } else { - $sql="DELETE FROM user_newtalk WHERE user_ip='{$this->mName}'"; - wfQuery ($sql,"User::saveSettings"); + $dbw->delete( 'user_newtalk', array( 'user_ip' => $this->mName ), $fname ); $wgMemc->delete( "$wgDBname:newtalk:ip:{$this->mName}" ); } } if ( 0 == $this->mId ) { return; } - $sql = "UPDATE user SET " . - "user_name= '" . wfStrencode( $this->mName ) . "', " . - "user_password= '" . wfStrencode( $this->mPassword ) . "', " . - "user_newpassword= '" . wfStrencode( $this->mNewpassword ) . "', " . - "user_email= '" . wfStrencode( $this->mEmail ) . "', " . - "user_options= '" . $this->encodeOptions() . "', " . - "user_rights= '" . wfStrencode( implode( ",", $this->mRights ) ) . "', " -. - "user_touched= '" . wfStrencode( $this->mTouched ) . - "' WHERE user_id={$this->mId}"; - wfQuery( $sql, "User::saveSettings" ); - #$wgMemc->replace( "$wgDBname:user:id:$this->mId", $this ); + $dbw->update( 'user', + array( /* SET */ + 'user_name' => $this->mName, + 'user_password' => $this->mPassword, + 'user_newpassword' => $this->mNewpassword, + 'user_real_name' => $this->mRealName, + 'user_email' => $this->mEmail, + 'user_options' => $this->encodeOptions(), + 'user_touched' => $dbw->timestamp($this->mTouched) + ), array( /* WHERE */ + 'user_id' => $this->mId + ), $fname + ); + $dbw->set( 'user_rights', 'user_rights', implode( ",", $this->mRights ), + 'user_id='. $this->mId, $fname ); $wgMemc->delete( "$wgDBname:user:id:$this->mId" ); } - # Checks if a user with the given name exists - # - function idForName() - { + /** + * Checks if a user with the given name exists, returns the ID + */ + function idForName() { + $fname = 'User::idForName'; + $gotid = 0; $s = trim( $this->mName ); - if ( 0 == strcmp( "", $s ) ) return 0; - - $sql = "SELECT user_id FROM user WHERE user_name='" . - wfStrencode( $s ) . "'"; - $res = wfQuery( $sql, "User::idForName" ); - if ( 0 == wfNumRows( $res ) ) { return 0; } - - $s = wfFetchObject( $res ); - if ( "" == $s ) return 0; - - $gotid = $s->user_id; - wfFreeResult( $res ); - return $gotid; - } + if ( 0 == strcmp( '', $s ) ) return 0; - function addToDatabase() - { - $sql = "INSERT INTO user (user_name,user_password,user_newpassword," . - "user_email, user_rights, user_options) " . - " VALUES ('" . wfStrencode( $this->mName ) . "', '" . - wfStrencode( $this->mPassword ) . "', '" . - wfStrencode( $this->mNewpassword ) . "', '" . - wfStrencode( $this->mEmail ) . "', '" . - wfStrencode( implode( ",", $this->mRights ) ) . "', '" . - $this->encodeOptions() . "')"; - wfQuery( $sql, "User::addToDatabase" ); - $this->mId = $this->idForName(); - } - - function spreadBlock() - { + $dbr =& wfGetDB( DB_SLAVE ); + $id = $dbr->selectField( 'user', 'user_id', array( 'user_name' => $s ), $fname ); + if ( $id === false ) { + $id = 0; + } + return $id; + } + + /** + * Add user object to the database + */ + function addToDatabase() { + $fname = 'User::addToDatabase'; + $dbw =& wfGetDB( DB_MASTER ); + $seqVal = $dbw->nextSequenceValue( 'user_user_id_seq' ); + $dbw->insert( 'user', + array( + 'user_id' => $seqVal, + 'user_name' => $this->mName, + 'user_password' => $this->mPassword, + 'user_newpassword' => $this->mNewpassword, + 'user_email' => $this->mEmail, + 'user_real_name' => $this->mRealName, + 'user_options' => $this->encodeOptions() + ), $fname + ); + $this->mId = $dbw->insertId(); + $dbw->insert( 'user_rights', + array( + 'user_id' => $this->mId, + 'user_rights' => implode( ',', $this->mRights ) + ), $fname + ); + + } + + function spreadBlock() { + global $wgIP; # If the (non-anonymous) user is blocked, this function will block any IP address # that they successfully log on from. - $fname = "User::spreadBlock"; - - if ( $this->mId == 0 || !$this->isBlocked()) { + $fname = 'User::spreadBlock'; + + wfDebug( "User:spreadBlock()\n" ); + if ( $this->mId == 0 ) { return; } - - $sql = "SELECT * FROM ipblocks WHERE ipb_user={$this->mId}"; - $res = wfQuery( $sql, $fname ); - if ( wfNumRows( $res ) == 0 ) { + + $userblock = Block::newFromDB( '', $this->mId ); + if ( !$userblock->isValid() ) { return; } - + # Check if this IP address is already blocked - $addr = getenv( "REMOTE_ADDR" ); - $sql = "SELECT * FROM ipblocks WHERE ipb_address='{$addr}'"; - $res2 = wfQuery( $sql, $fname ); - if ( wfNumRows( $res2 ) != 0 ) { + $ipblock = Block::newFromDB( $wgIP ); + if ( $ipblock->isValid() ) { + # Just update the timestamp + $ipblock->updateTimestamp(); return; } - - $row = wfFetchObject( $res ); - $reason = str_replace( "$1", $this->getName(), wfMsg( "autoblocker" ) ); - $reason = str_replace( "$2", $row->ipb_reason, $reason ); - - $addr = getenv( "REMOTE_ADDR" ); - $sql = "INSERT INTO ipblocks(ipb_address, ipb_user, ipb_by, " . - "ipb_reason, ipb_timestamp) VALUES ('{$addr}', 0, {$row->ipb_by}," . - "'{$reason}', '" . wfTimestampNow() . "')"; - wfQuery( $sql, $fname ); - - wfFreeResult( $res ); - wfFreeResult( $res2 ); + + # Make a new block object with the desired properties + wfDebug( "Autoblocking {$this->mName}@{$wgIP}\n" ); + $ipblock->mAddress = $wgIP; + $ipblock->mUser = 0; + $ipblock->mBy = $userblock->mBy; + $ipblock->mReason = wfMsg( 'autoblocker', $this->getName(), $userblock->mReason ); + $ipblock->mTimestamp = wfTimestampNow(); + $ipblock->mAuto = 1; + # If the user is already blocked with an expiry date, we don't + # want to pile on top of that! + if($userblock->mExpiry) { + $ipblock->mExpiry = min ( $userblock->mExpiry, Block::getAutoblockExpiry( $ipblock->mTimestamp )); + } else { + $ipblock->mExpiry = Block::getAutoblockExpiry( $ipblock->mTimestamp ); + } + + # Insert it + $ipblock->insert(); + + } + + function getPageRenderingHash() { + global $wgLang; + if( $this->mHash ){ + return $this->mHash; + } + + // stubthreshold is only included below for completeness, + // it will always be 0 when this function is called by parsercache. + + $confstr = $this->getOption( 'math' ); + $confstr .= '!' . $this->getOption( 'highlightbroken' ); + $confstr .= '!' . $this->getOption( 'stubthreshold' ); + $confstr .= '!' . $this->getOption( 'editsection' ); + $confstr .= '!' . $this->getOption( 'editsectiononrightclick' ); + $confstr .= '!' . $this->getOption( 'showtoc' ); + $confstr .= '!' . $this->getOption( 'date' ); + $confstr .= '!' . $this->getOption( 'numberheadings' ); + + // add in language variant option if there are multiple variants + // supported by the language object + if(sizeof($wgLang->getVariants())>1) { + $confstr .= '!' . $this->getOption( 'variant' ); + } + + $this->mHash = $confstr; + return $confstr ; + } + + function isAllowedToCreateAccount() { + global $wgWhitelistAccount; + $allowed = false; + + if (!$wgWhitelistAccount) { return 1; }; // default behaviour + foreach ($wgWhitelistAccount as $right => $ok) { + $userHasRight = (!strcmp($right, 'user') || in_array($right, $this->getRights())); + $allowed |= ($ok && $userHasRight); + } + return $allowed; + } + + /** + * Set mDataLoaded, return previous value + * Use this to prevent DB access in command-line scripts or similar situations + */ + function setLoaded( $loaded ) { + return wfSetVar( $this->mDataLoaded, $loaded ); + } + + function getUserPage() { + return Title::makeTitle( NS_USER, $this->mName ); + } + + /** + * @static + */ + function getMaxID() { + $dbr =& wfGetDB( DB_SLAVE ); + return $dbr->selectField( 'user', 'max(user_id)', false ); + } + + /** + * Determine whether the user is a newbie. Newbies are either + * anonymous IPs, or the 1% most recently created accounts. + * Bots and sysops are excluded. + * @return bool True if it is a newbie. + */ + function isNewbie() { + return $this->mId > User::getMaxID() * 0.99 && !$this->isSysop() && !$this->isBot() || $this->getID() == 0; + } + + /** + * Check to see if the given clear-text password is one of the accepted passwords + * @param string $password User password. + * @return bool True if the given password is correct otherwise False. + */ + function checkPassword( $password ) { + $this->loadFromDatabase(); + $ep = $this->encryptPassword( $password ); + if ( 0 == strcmp( $ep, $this->mPassword ) ) { + return true; + } elseif ( 0 == strcmp( $ep, $this->mNewpassword ) ) { + return true; + } elseif ( function_exists( 'iconv' ) ) { + # Some wikis were converted from ISO 8859-1 to UTF-8, the passwords can't be converted + # Check for this with iconv +/* $cp1252hash = $this->encryptPassword( iconv( 'UTF-8', 'WINDOWS-1252', $password ) ); + if ( 0 == strcmp( $cp1252hash, $this->mPassword ) ) { + return true; + }*/ + } + return false; } }