|| strlen( $name ) > $wgMaxNameChars
|| $name != $wgContLang->ucfirst( $name ) )
return false;
-
+
// Ensure that the name can't be misresolved as a different title,
// such as with extra namespace keys at the start.
$parsed = Title::newFromText( $name );
|| $parsed->getNamespace()
|| strcmp( $name, $parsed->getPrefixedText() ) )
return false;
- else
- return true;
+
+ // Check an additional blacklist of troublemaker characters.
+ // Should these be merged into the title char list?
+ $unicodeBlacklist = '/[' .
+ '\x{0080}-\x{009f}' . # iso-8859-1 control chars
+ '\x{00a0}' . # non-breaking space
+ '\x{2000}-\x{200f}' . # various whitespace
+ '\x{2028}-\x{202f}' . # breaks and control chars
+ '\x{3000}' . # ideographic space
+ '\x{e000}-\x{f8ff}' . # private use
+ ']/u';
+ if( preg_match( $unicodeBlacklist, $name ) ) {
+ return false;
+ }
+
+ return true;
}
/**
$fname = 'User::loadDefaults' . $n;
wfProfileIn( $fname );
- global $wgContLang, $wgDBname;
+ global $wgContLang, $wgCookiePrefix;
global $wgNamespacesToBeSearchedDefault;
$this->mId = 0;
$this->setToken(); # Random
$this->mHash = false;
- if ( isset( $_COOKIE[$wgDBname.'LoggedOut'] ) ) {
- $this->mTouched = wfTimestamp( TS_MW, $_COOKIE[$wgDBname.'LoggedOut'] );
+ if ( isset( $_COOKIE[$wgCookiePrefix.'LoggedOut'] ) ) {
+ $this->mTouched = wfTimestamp( TS_MW, $_COOKIE[$wgCookiePrefix.'LoggedOut'] );
}
else {
$this->mTouched = '0'; # Allow any pages to be cached
}
$this->mRegistration = wfTimestamp( TS_MW );
-
+
wfProfileOut( $fname );
}
* @static
*/
function loadFromSession() {
- global $wgMemc, $wgDBname;
+ global $wgMemc, $wgDBname, $wgCookiePrefix;
if ( isset( $_SESSION['wsUserID'] ) ) {
if ( 0 != $_SESSION['wsUserID'] ) {
} else {
return new User();
}
- } else if ( isset( $_COOKIE["{$wgDBname}UserID"] ) ) {
- $sId = intval( $_COOKIE["{$wgDBname}UserID"] );
+ } else if ( isset( $_COOKIE["{$wgCookiePrefix}UserID"] ) ) {
+ $sId = intval( $_COOKIE["{$wgCookiePrefix}UserID"] );
$_SESSION['wsUserID'] = $sId;
} else {
return new User();
}
if ( isset( $_SESSION['wsUserName'] ) ) {
$sName = $_SESSION['wsUserName'];
- } else if ( isset( $_COOKIE["{$wgDBname}UserName"] ) ) {
- $sName = $_COOKIE["{$wgDBname}UserName"];
+ } else if ( isset( $_COOKIE["{$wgCookiePrefix}UserName"] ) ) {
+ $sName = $_COOKIE["{$wgCookiePrefix}UserName"];
$_SESSION['wsUserName'] = $sName;
} else {
return new User();
} else {
wfDebug( "User::loadFromSession() got from cache!\n" );
}
-
+
if ( isset( $_SESSION['wsToken'] ) ) {
$passwordCorrect = $_SESSION['wsToken'] == $user->mToken;
- } else if ( isset( $_COOKIE["{$wgDBname}Token"] ) ) {
- $passwordCorrect = $user->mToken == $_COOKIE["{$wgDBname}Token"];
+ } else if ( isset( $_COOKIE["{$wgCookiePrefix}Token"] ) ) {
+ $passwordCorrect = $user->mToken == $_COOKIE["{$wgCookiePrefix}Token"];
} else {
return new User(); # Can't log in from session
}
$this->mGroups[] = $row->ug_group;
}
$implicitGroups = array( '*', 'user' );
-
+
global $wgAutoConfirmAge;
$accountAge = time() - wfTimestampOrNull( TS_UNIX, $this->mRegistration );
if( $accountAge >= $wgAutoConfirmAge ) {
$implicitGroups[] = 'autoconfirmed';
}
-
+
$effectiveGroups = array_merge( $implicitGroups, $this->mGroups );
$this->mRights = $this->getGroupPermissions( $effectiveGroups );
}
return (bool)$this->mNewtalk;
}
+ /**
+ * Return the talk page(s) this user has new messages on.
+ */
+ function getNewMessageLinks() {
+ global $wgDBname;
+ $talks = array();
+ if (!wfRunHooks('UserRetrieveNewTalks', array(&$this, &$talks)))
+ return $talks;
+
+ if (!$this->getNewtalk())
+ return array();
+ $up = $this->getUserPage();
+ $utp = $up->getTalkPage();
+ return array(array("wiki" => $wgDBname, "link" => $utp->getLocalURL()));
+ }
+
+
/**
* Perform a user_newtalk check on current slaves; if the memcached data
* is funky we don't want newtalk state to get stuck on save, as that's
array( $field => $id ), $fname );
return $ok !== false;
}
-
+
/**
- * Add or update the
+ * Add or update the
* @param string $field
* @param mixed $id
* @access private
wfDebug( "$fname: set on ($field, $id)\n" );
return true;
}
-
+
/**
+ * Clear the new messages flag for the given user
* @param string $field
* @param mixed $id
* @access private
wfDebug( "$fname: killed on ($field, $id)\n" );
return true;
}
-
+
/**
* Update the 'You have new messages!' status.
* @param bool $val
if( wfReadOnly() ) {
return;
}
-
+
$this->loadFromDatabase();
$this->mNewtalk = $val;
$fname = 'User::setNewtalk';
-
+
if( $this->isAnon() ) {
$field = 'user_ip';
$id = $this->getName();
$field = 'user_id';
$id = $this->getId();
}
-
+
if( $val ) {
$changed = $this->updateNewtalk( $field, $id );
} else {
$changed = $this->deleteNewtalk( $field, $id );
}
-
+
if( $changed ) {
if( $this->isAnon() ) {
// Anons have a separate memcached space, since
// user records aren't kept for them.
global $wgDBname, $wgMemc;
- $key = "$wgDBname:newtalk:ip:$value";
+ $key = "$wgDBname:newtalk:ip:$val";
$wgMemc->set( $key, $val ? 1 : 0 );
} else {
if( $val ) {
$this->mRealName = $str;
}
+ /**
+ * @param string $oname The option to check
+ * @return string
+ */
function getOption( $oname ) {
$this->loadFromDatabase();
if ( array_key_exists( $oname, $this->mOptions ) ) {
}
}
+ /**
+ * @param string $oname The option to check
+ * @return bool False if the option is not selected, true if it is
+ */
+ function getBoolOption( $oname ) {
+ return (bool)$this->getOption( $oname );
+ }
+
function setOption( $oname, $val ) {
$this->loadFromDatabase();
if ( $oname == 'skin' ) {
}
/**
- * Remove the user from the given group.
+ * Add the user to the given group.
* This takes immediate effect.
* @string $group
*/
$fname = 'User::getSkin';
wfProfileIn( $fname );
- # get all skin names available
- $skinNames = Skin::getSkinNames();
-
# get the user skin
$userSkin = $this->getOption( 'skin' );
$userSkin = $wgRequest->getVal('useskin', $userSkin);
-
+
$this->mSkin =& Skin::newFromKey( $userSkin );
wfProfileOut( $fname );
}
function clearNotification( &$title ) {
global $wgUser, $wgUseEnotif;
+
if ($title->getNamespace() == NS_USER_TALK &&
$title->getText() == $this->getName() ) {
+ if (!wfRunHooks('UserClearNewTalkNotification', array(&$this)))
+ return;
$this->setNewtalk( false );
}
-
+
if( !$wgUseEnotif ) {
return;
}
}
function setCookies() {
- global $wgCookieExpiration, $wgCookiePath, $wgCookieDomain, $wgDBname;
+ global $wgCookieExpiration, $wgCookiePath, $wgCookieDomain, $wgCookieSecure, $wgDBname;
if ( 0 == $this->mId ) return;
$this->loadFromDatabase();
$exp = time() + $wgCookieExpiration;
$_SESSION['wsUserID'] = $this->mId;
- setcookie( $wgDBname.'UserID', $this->mId, $exp, $wgCookiePath, $wgCookieDomain );
+ setcookie( $wgDBname.'UserID', $this->mId, $exp, $wgCookiePath, $wgCookieDomain, $wgCookieSecure );
$_SESSION['wsUserName'] = $this->getName();
- setcookie( $wgDBname.'UserName', $this->getName(), $exp, $wgCookiePath, $wgCookieDomain );
+ setcookie( $wgDBname.'UserName', $this->getName(), $exp, $wgCookiePath, $wgCookieDomain, $wgCookieSecure );
$_SESSION['wsToken'] = $this->mToken;
if ( 1 == $this->getOption( 'rememberpassword' ) ) {
- setcookie( $wgDBname.'Token', $this->mToken, $exp, $wgCookiePath, $wgCookieDomain );
+ setcookie( $wgDBname.'Token', $this->mToken, $exp, $wgCookiePath, $wgCookieDomain, $wgCookieSecure );
} else {
setcookie( $wgDBname.'Token', '', time() - 3600 );
}
* It will clean the session cookie
*/
function logout() {
- global $wgCookiePath, $wgCookieDomain, $wgDBname;
+ global $wgCookiePath, $wgCookieDomain, $wgCookieSecure, $wgDBname;
$this->loadDefaults();
$this->setLoaded( true );
$_SESSION['wsUserID'] = 0;
- setcookie( $wgDBname.'UserID', '', time() - 3600, $wgCookiePath, $wgCookieDomain );
- setcookie( $wgDBname.'Token', '', time() - 3600, $wgCookiePath, $wgCookieDomain );
+ setcookie( $wgDBname.'UserID', '', time() - 3600, $wgCookiePath, $wgCookieDomain, $wgCookieSecure );
+ setcookie( $wgDBname.'Token', '', time() - 3600, $wgCookiePath, $wgCookieDomain, $wgCookieSecure );
# Remember when user logged out, to prevent seeing cached pages
- setcookie( $wgDBname.'LoggedOut', wfTimestampNow(), time() + 86400, $wgCookiePath, $wgCookieDomain );
+ setcookie( $wgDBname.'LoggedOut', wfTimestampNow(), time() + 86400, $wgCookiePath, $wgCookieDomain, $wgCookieSecure );
}
/**
}
+ /**
+ * Generate a string which will be different for any combination of
+ * user options which would produce different parser output.
+ * This will be used as part of the hash key for the parser cache,
+ * so users will the same options can share the same cached data
+ * safely.
+ *
+ * Extensions which require it should install 'PageRenderingHash' hook,
+ * which will give them a chance to modify this key based on their own
+ * settings.
+ *
+ * @return string
+ */
function getPageRenderingHash() {
global $wgContLang;
if( $this->mHash ){
$extra = $wgContLang->getExtraHashOptions();
$confstr .= $extra;
+ // Give a chance for extensions to modify the hash, if they have
+ // extra options or other effects on the parser cache.
+ wfRunHooks( 'PageRenderingHash', array( &$confstr ) );
+
$this->mHash = $confstr;
- return $confstr ;
+ return $confstr;
}
function isAllowedToCreateAccount() {
array_keys( $wgGroupPermissions ),
array( '*', 'user', 'autoconfirmed' ) );
}
-
}
?>