*
*/
require_once( 'WatchedItem.php' );
+require_once( 'Group.php' );
# Number of characters in user_token field
define( 'USER_TOKEN_LENGTH', 32 );
var $mToken;
var $mRealName;
var $mHash;
+ /** Array of group id the user belong to */
+ var $mGroups;
/**#@-*/
/** Construct using User:loadDefaults() */
global $wgContLang, $wgIP;
global $wgNamespacesToBeSearchedDefault;
- $this->mId = $this->mNewtalk = 0;
+ $this->mId = 0;
+ $this->mNewtalk = -1;
$this->mName = $wgIP;
$this->mRealName = $this->mEmail = '';
$this->mPassword = $this->mNewpassword = '';
$this->mRights = array();
+ $this->mGroups = array();
+
// Getting user defaults only if we have an available language
if(isset($wgContLang)) { $this->loadDefaultFromLanguage(); }
foreach ( $defOpt as $oname => $val ) {
$this->mOptions[$oname] = $val;
}
- /*
- default language setting
- */
- $this->setOption('variant', $wgContLang->getPreferredVariant());
- $this->setOption('language', $wgContLang->getPreferredVariant());
+ /*
+ default language setting
+ */
+ $this->setOption('variant', $wgContLang->getPreferredVariant());
+ $this->setOption('language', $wgContLang->getPreferredVariant());
}
/**
* Load a user from the database
*/
function loadFromDatabase() {
- global $wgCommandLineMode;
+ global $wgCommandLineMode, $wgAnonGroupId, $wgLoggedInGroupId;
$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) {
- $res = $dbr->select( 'user_newtalk', 1, array( 'user_id' => $this->mId ), $fname );
-
- if ( $dbr->numRows($res)>0 ) {
- $this->mNewtalk= 1;
- }
- $dbr->freeResult( $res );
- } else {
- global $wgDBname, $wgMemc;
- $key = "$wgDBname:newtalk:ip:{$this->mName}";
- $newtalk = $wgMemc->get( $key );
- if( ! is_integer( $newtalk ) ){
- $res = $dbr->select( 'user_newtalk', 1, array( 'user_ip' => $this->mName ), $fname );
-
- $this->mNewtalk = $dbr->numRows( $res ) > 0 ? 1 : 0;
- $dbr->freeResult( $res );
-
- $wgMemc->set( $key, $this->mNewtalk, time() ); // + 1800 );
- } else {
- $this->mNewtalk = $newtalk ? 1 : 0;
- }
- }
+ /** Anonymous user */
if(!$this->mId) {
+ /** Get rights */
+ $anong = Group::newFromId($wgAnonGroupId);
+ if (!$anong)
+ wfDebugDieBacktrace("Please update your database schema "
+ ."and populate initial group data from "
+ ."maintenance/archives patches");
+ $anong->loadFromDatabase();
+ $this->mRights = explode(',', $anong->getRights());
$this->mDataLoaded = true;
return;
} # the following stuff is for non-anonymous users only
+ $dbr =& wfGetDB( DB_SLAVE );
$s = $dbr->selectRow( 'user', array( 'user_name','user_password','user_newpassword','user_email',
'user_real_name','user_options','user_touched', 'user_token' ),
array( 'user_id' => $this->mId ), $fname );
$this->mNewpassword = $s->user_newpassword;
$this->decodeOptions( $s->user_options );
$this->mTouched = wfTimestamp(TS_MW,$s->user_touched);
- $this->mRights = explode( ",", strtolower(
- $dbr->selectField( 'user_rights', 'user_rights', array( 'user_id' => $this->mId ) )
- ) );
$this->mToken = $s->user_token;
+
+ // Get groups id
+ $res = $dbr->select( 'user_groups', array( 'ug_group' ), array( 'ug_user' => $this->mId ) );
+
+ while($group = $dbr->fetchRow($res)) {
+ $this->mGroups[] = $group[0];
+ }
+
+ // add the default group for logged in user
+ $this->mGroups[] = $wgLoggedInGroupId;
+
+ $this->mRights = array();
+ // now we merge groups rights to get this user rights
+ foreach($this->mGroups as $aGroupId) {
+ $g = Group::newFromId($aGroupId);
+ $g->loadFromDatabase();
+ $this->mRights = array_merge($this->mRights, explode(',', $g->getRights()));
+ }
+
+ // array merge duplicate rights which are part of several groups
+ $this->mRights = array_unique($this->mRights);
+
+ $dbr->freeResult($res);
}
$this->mDataLoaded = true;
}
function getNewtalk() {
+ $fname = 'User::getNewtalk';
$this->loadFromDatabase();
+
+ # Load the newtalk status if it is unloaded (mNewtalk=-1)
+ if ( $this->mNewtalk == -1 ) {
+ $this->mNewtalk=0; # reset talk page status
+ $dbr =& wfGetDB( DB_SLAVE );
+ if($this->mId) {
+ $res = $dbr->select( 'user_newtalk', 1, array( 'user_id' => $this->mId ), $fname );
+
+ if ( $dbr->numRows($res)>0 ) {
+ $this->mNewtalk= 1;
+ }
+ $dbr->freeResult( $res );
+ } else {
+ global $wgDBname, $wgMemc;
+ $key = "$wgDBname:newtalk:ip:{$this->mName}";
+ $newtalk = $wgMemc->get( $key );
+ if( ! is_integer( $newtalk ) ){
+ $res = $dbr->select( 'user_newtalk', 1, array( 'user_ip' => $this->mName ), $fname );
+
+ $this->mNewtalk = $dbr->numRows( $res ) > 0 ? 1 : 0;
+ $dbr->freeResult( $res );
+
+ $wgMemc->set( $key, $this->mNewtalk, time() ); // + 1800 );
+ } else {
+ $this->mNewtalk = $newtalk ? 1 : 0;
+ }
+ }
+ }
+
return ( 0 != $this->mNewtalk );
}
$this->loadFromDatabase();
return $this->mRights;
}
-
+
function addRight( $rname ) {
$this->loadFromDatabase();
array_push( $this->mRights, $rname );
$this->invalidateCache();
}
+ function getGroups() {
+ $this->loadFromDatabase();
+ return $this->mGroups;
+ }
+
+ function setGroups($groups) {
+ $this->loadFromDatabase();
+ $this->mGroups = $groups;
+ $this->invalidateCache();
+ }
+
+ /**
+ * Check if a user is sysop
+ * Die with backtrace. Use User:isAllowed() instead.
+ * @deprecated
+ */
function isSysop() {
+ /**
$this->loadFromDatabase();
if ( 0 == $this->mId ) { return false; }
return in_array( 'sysop', $this->mRights );
+ */
+ wfDebugDieBacktrace("User::isSysop() is deprecated. Use User::isAllowed() instead");
}
+ /** @deprecated */
function isDeveloper() {
+ /**
$this->loadFromDatabase();
if ( 0 == $this->mId ) { return false; }
return in_array( 'developer', $this->mRights );
+ */
+ wfDebugDieBacktrace("User::isDeveloper() is deprecated. Use User::isAllowed() instead");
}
+ /** @deprecated */
function isBureaucrat() {
+ /**
$this->loadFromDatabase();
if ( 0 == $this->mId ) { return false; }
return in_array( 'bureaucrat', $this->mRights );
+ */
+ wfDebugDieBacktrace("User::isBureaucrat() is deprecated. Use User::isAllowed() instead");
}
/**
* Whether the user is a bot
+ * @todo need to be migrated to the new user level management sytem
*/
function isBot() {
$this->loadFromDatabase();
return in_array( 'bot', $this->mRights );
}
+ /**
+ * Check if user is allowed to access a feature / make an action
+ * @param string $action Action to be checked (see $wgAvailableRights in Defines.php for possible actions).
+ * @return boolean True: action is allowed, False: action should not be allowed
+ */
+ function isAllowed($action='') {
+ $this->loadFromDatabase();
+ return in_array( $action , $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;
+ global $IP;
if ( ! isset( $this->mSkin ) ) {
# get all skin names available
$skinNames = Skin::getSkinNames();
$fname = 'User::saveSettings';
$dbw =& wfGetDB( DB_MASTER );
- if ( ! $this->mNewtalk ) {
+ if ( ! $this->getNewtalk() ) {
# Delete user_newtalk row
if( $this->mId ) {
$dbw->delete( 'user_newtalk', array( 'user_id' => $this->mId ), $fname );
'user_id' => $this->mId
), $fname
);
- $dbw->set( 'user_rights', 'user_rights', implode( ",", $this->mRights ),
- 'user_id='. $this->mId, $fname );
+ $dbw->set( 'user_rights', 'ur_rights', implode( ',', $this->mRights ),
+ 'ur_user='. $this->mId, $fname );
$wgMemc->delete( "$wgDBname:user:id:$this->mId" );
+
+ // delete old groups
+ $dbw->delete( 'user_groups', array( 'ug_user' => $this->mId), $fname);
+
+ // save new ones
+ foreach ($this->mGroups as $group) {
+ $dbw->replace( 'user_groups',
+ array(array('ug_user','ug_group')),
+ array(
+ 'ug_user' => $this->mId,
+ 'ug_group' => $group
+ ), $fname
+ );
+ }
}
/**
$this->mId = $dbw->insertId();
$dbw->insert( 'user_rights',
array(
- 'user_id' => $this->mId,
- 'user_rights' => implode( ',', $this->mRights )
+ 'ur_user' => $this->mId,
+ 'ur_rights' => implode( ',', $this->mRights )
), $fname
);
-
+
+ foreach ($this->mGroups as $group) {
+ $dbw->insert( 'user_groups',
+ array(
+ 'ug_user' => $this->mId,
+ 'ug_group' => $group
+ ), $fname
+ );
+ }
}
function spreadBlock() {
$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($wgContLang->getVariants())>1) {
- $confstr .= '!' . $this->getOption( 'variant' );
- }
+ $confstr .= '!' . $this->getOption( 'language' );
+ // add in language variant option if there are multiple variants
+ // supported by the language object
+ if(sizeof($wgContLang->getVariants())>1) {
+ $confstr .= '!' . $this->getOption( 'variant' );
+ }
$this->mHash = $confstr;
return $confstr ;
*/
function checkPassword( $password ) {
$this->loadFromDatabase();
+
+ global $wgAuth;
+ if( $wgAuth->authenticate( $this->getName(), $password ) ) {
+ return true;
+ } elseif( $wgAuth->strict() ) {
+ /* Auth plugin doesn't allow local authentication */
+ return false;
+ }
+
$ep = $this->encryptPassword( $password );
if ( 0 == strcmp( $ep, $this->mPassword ) ) {
return true;