35 define(
'EDIT_TOKEN_SUFFIX', Token::SUFFIX );
100 'mEmailAuthenticated',
102 'mEmailTokenExpires',
148 'editusercssjs', # deprecated
161 'move-categorypages',
162 'move-rootuserpages',
166 'override-export-depth',
189 'userrights-interwiki',
348 return ( !defined(
'MW_NO_SESSION' ) && $wgFullyInitialised ) ||
349 $this->mLoadedItems ===
true || $this->mFrom !==
'session';
360 if ( $this->mLoadedItems ===
true ) {
366 $this->mLoadedItems =
true;
367 $this->queryFlagsUsed =
$flags;
370 if ( !$wgFullyInitialised && $this->mFrom ===
'session' ) {
372 ->warning(
'User::loadFromSession called before the end of Setup.php', [
373 'exception' =>
new Exception(
'User::loadFromSession called before the end of Setup.php' ),
376 $this->mLoadedItems = $oldLoadedItems;
380 switch ( $this->mFrom ) {
386 if (
wfGetLB()->hasOrMadeRecentMasterChanges() ) {
387 $flags |= self::READ_LATEST;
388 $this->queryFlagsUsed =
$flags;
391 $this->mId = self::idFromName( $this->mName,
$flags );
407 Hooks::run(
'UserLoadAfterLoadFromSession', [ $this ] );
410 throw new UnexpectedValueException(
411 "Unrecognised value for User->mFrom: \"{$this->mFrom}\"" );
421 if ( $this->mId == 0 ) {
439 $this->mLoadedItems =
true;
440 $this->queryFlagsUsed =
$flags;
450 public static function purge( $wikiId, $userId ) {
452 $key =
$cache->makeGlobalKey(
'user',
'id', $wikiId, $userId );
473 $data =
$cache->getWithSetCallback(
476 function ( $oldValue, &$ttl,
array &$setOpts ) {
478 wfDebug(
"User: cache miss for user {$this->mId}\n" );
485 foreach ( self::$mCacheVars
as $name ) {
486 $data[
$name] = $this->$name;
492 [
'pcTTL' => $cache::TTL_PROC_LONG,
'version' => self::VERSION ]
496 foreach ( self::$mCacheVars
as $name ) {
497 $this->$name = $data[
$name];
523 if ( $validate ===
true ) {
526 $name = self::getCanonicalName(
$name, $validate );
527 if (
$name ===
false ) {
534 $u->setItemLoaded(
'name' );
549 $u->setItemLoaded(
'id' );
565 $db = (
$flags & self::READ_LATEST ) == self::READ_LATEST
569 $id = $db->selectField(
573 'user_email_token' => md5(
$code ),
574 'user_email_token_expires > ' . $db->addQuotes( $db->timestamp() ),
590 $user->mFrom =
'session';
611 $user->loadFromRow( $row, $data );
654 'validate' =>
'valid',
660 if (
$name ===
false ) {
664 $fields = self::selectFields();
665 if ( $wgDisableAuthManager ) {
666 $fields = array_merge( $fields, [
'user_password',
'user_newpassword' ] );
670 $row = $dbw->selectRow(
673 [
'user_name' =>
$name ],
680 $user = self::newFromRow( $row );
684 if ( !
$user->mEmail &&
$user->mToken === self::INVALID_TOKEN ) {
685 if ( $wgDisableAuthManager ) {
689 $password = $passwordFactory->newFromCiphertext( $row->user_password );
691 wfDebug(
'Invalid password hash found in database.' );
695 $newpassword = $passwordFactory->newFromCiphertext( $row->user_newpassword );
697 wfDebug(
'Invalid password hash found in database.' );
703 $canAuthenticate = AuthManager::singleton()->userCanAuthenticate(
$name );
706 if (
$user->mEmail ||
$user->mToken !== self::INVALID_TOKEN || $canAuthenticate ) {
712 if ( $wgDisableAuthManager ) {
717 'user_password' => $nopass,
718 'user_newpassword' => $nopass,
719 'user_newpass_time' => null,
721 [
'user_id' =>
$user->getId() ],
725 AuthManager::singleton()->revokeAccessForUser(
$name );
728 $user->invalidateEmail();
729 $user->mToken = self::INVALID_TOKEN;
730 $user->saveSettings();
731 SessionManager::singleton()->preventSessionsForUser(
$user->getName() );
744 public static function whoIs( $id ) {
766 if ( is_null( $nt ) ) {
771 if ( !(
$flags & self::READ_LATEST ) && isset( self::$idCacheByName[
$name] ) ) {
772 return self::$idCacheByName[
$name];
781 [
'user_name' => $nt->getText() ],
786 if (
$s ===
false ) {
794 if ( count( self::$idCacheByName ) > 1000 ) {
795 self::$idCacheByName = [];
805 self::$idCacheByName = [];
825 return preg_match(
'/^\d{1,3}\.\d{1,3}\.\d{1,3}\.(?:xxx|\d{1,3})$/',
$name )
845 || strpos(
$name,
'/' ) !==
false
846 || strlen(
$name ) > $wgMaxNameChars
855 if ( is_null( $parsed )
856 || $parsed->getNamespace()
857 || strcmp(
$name, $parsed->getPrefixedText() ) ) {
863 $unicodeBlacklist =
'/[' .
864 '\x{0080}-\x{009f}' . # iso-8859-1 control chars
865 '\x{00a0}' . # non-breaking space
866 '\x{2000}-\x{200f}' . # various whitespace
867 '\x{2028}-\x{202f}' . # breaks
and control chars
868 '\x{3000}' . # ideographic space
869 '\x{e000}-\x{f8ff}' . #
private use
871 if ( preg_match( $unicodeBlacklist,
$name ) ) {
892 if ( !self::isValidUserName(
$name ) ) {
896 static $reservedUsernames =
false;
897 if ( !$reservedUsernames ) {
899 Hooks::run(
'UserGetReservedNames', [ &$reservedUsernames ] );
903 foreach ( $reservedUsernames
as $reserved ) {
904 if ( substr( $reserved, 0, 4 ) ==
'msg:' ) {
905 $reserved =
wfMessage( substr( $reserved, 4 ) )->inContentLanguage()->text();
907 if ( $reserved ==
$name ) {
925 if ( $groups === [] ) {
929 $groups = array_unique( (
array)$groups );
932 $conds = [
'ug_group' => $groups ];
933 if ( $after !== null ) {
934 $conds[] =
'ug_user > ' . (int)$after;
938 $ids =
$dbr->selectFieldValues(
945 'ORDER BY' =>
'ug_user',
970 if ( strlen(
$name ) > 235 ) {
972 ": '$name' invalid due to length" );
977 if ( $wgInvalidUsernameCharacters !==
'' ) {
978 if ( preg_match(
'/[' . preg_quote( $wgInvalidUsernameCharacters,
'/' ) .
']/',
$name ) ) {
980 ": '$name' invalid due to wgInvalidUsernameCharacters" );
985 return self::isUsableName(
$name );
1011 foreach (
$result->getErrorsByType(
'error' )
as $error ) {
1014 foreach (
$result->getErrorsByType(
'warning' )
as $warning ) {
1046 $wgPasswordPolicy[
'policies'],
1047 $wgPasswordPolicy[
'checks']
1059 $status->merge( $upp->checkUserPassword( $this, $password, $purpose ) );
1061 } elseif (
$result ===
true ) {
1087 # Reject names containing '#'; these will be cleaned up
1088 # with title normalisation, but then it's too late to
1090 if ( strpos(
$name,
'#' ) !==
false ) {
1096 $t = ( $validate !==
false ) ?
1099 if ( is_null(
$t ) ||
$t->getNamespace() !==
NS_USER ||
$t->isExternal() ) {
1104 $name = AuthManager::callLegacyAuthPlugin(
1105 'getCanonicalName', [
$t->getText() ],
$t->getText()
1108 switch ( $validate ) {
1127 throw new InvalidArgumentException(
1128 'Invalid parameter value for $validate in ' . __METHOD__ );
1143 $user = self::newFromId( $uid );
1144 return $user->getEditCount();
1168 $this->mName =
$name;
1169 $this->mRealName =
'';
1171 $this->mOptionOverrides = null;
1172 $this->mOptionsLoaded =
false;
1174 $loggedOut = $this->mRequest && !defined(
'MW_NO_SESSION' )
1175 ? $this->mRequest->getSession()->getLoggedOutTimestamp() : 0;
1176 if ( $loggedOut !== 0 ) {
1179 $this->mTouched =
'1'; # Allow any
pages to be
cached
1182 $this->mToken = null;
1183 $this->mEmailAuthenticated = null;
1184 $this->mEmailToken =
'';
1185 $this->mEmailTokenExpires = null;
1187 $this->mGroups = [];
1205 return ( $this->mLoadedItems ===
true && $all ===
'all' ) ||
1206 ( isset( $this->mLoadedItems[$item] ) && $this->mLoadedItems[$item] ===
true );
1215 if ( is_array( $this->mLoadedItems ) ) {
1216 $this->mLoadedItems[$item] =
true;
1235 $session = $this->
getRequest()->getSession();
1236 $user = $session->getUser();
1237 if (
$user->isLoggedIn() ) {
1240 $session->set(
'wsUserID', $this->
getId() );
1241 $session->set(
'wsUserName', $this->
getName() );
1242 $session->set(
'wsToken', $this->
getToken() );
1258 $this->mId = intval( $this->mId );
1260 if ( !$this->mId ) {
1269 $s = $db->selectRow(
1271 self::selectFields(),
1272 [
'user_id' => $this->mId ],
1277 $this->queryFlagsUsed =
$flags;
1280 if (
$s !==
false ) {
1283 $this->mGroups = null;
1306 $this->mGroups = null;
1308 if ( isset( $row->user_name ) ) {
1309 $this->mName = $row->user_name;
1310 $this->mFrom =
'name';
1316 if ( isset( $row->user_real_name ) ) {
1317 $this->mRealName = $row->user_real_name;
1323 if ( isset( $row->user_id ) ) {
1324 $this->mId = intval( $row->user_id );
1325 $this->mFrom =
'id';
1331 if ( isset( $row->user_id ) && isset( $row->user_name ) ) {
1332 self::$idCacheByName[$row->user_name] = $row->user_id;
1335 if ( isset( $row->user_editcount ) ) {
1336 $this->mEditCount = $row->user_editcount;
1341 if ( isset( $row->user_touched ) ) {
1347 if ( isset( $row->user_token ) ) {
1351 $this->mToken = rtrim( $row->user_token,
" \0" );
1352 if ( $this->mToken ===
'' ) {
1353 $this->mToken = null;
1359 if ( isset( $row->user_email ) ) {
1360 $this->mEmail = $row->user_email;
1362 $this->mEmailToken = $row->user_email_token;
1370 $this->mLoadedItems =
true;
1373 if ( is_array( $data ) ) {
1374 if ( isset( $data[
'user_groups'] ) && is_array( $data[
'user_groups'] ) ) {
1375 $this->mGroups = $data[
'user_groups'];
1377 if ( isset( $data[
'user_properties'] ) && is_array( $data[
'user_properties'] ) ) {
1390 $user->loadGroups();
1391 $user->loadOptions();
1392 foreach ( self::$mCacheVars
as $var ) {
1393 $this->$var =
$user->$var;
1401 if ( is_null( $this->mGroups ) ) {
1402 $db = ( $this->queryFlagsUsed & self::READ_LATEST )
1405 $res = $db->select(
'user_groups',
1407 [
'ug_user' => $this->mId ],
1409 $this->mGroups = [];
1410 foreach (
$res as $row ) {
1411 $this->mGroups[] = $row->ug_group;
1438 if ( !count( $toPromote ) ) {
1447 foreach ( $toPromote
as $group ) {
1451 Hooks::run(
'UserGroupsChanged', [ $this, $toPromote, [],
false,
false ] );
1452 AuthManager::callLegacyAuthPlugin(
'updateExternalDBGroups', [ $this, $toPromote ] );
1454 $newGroups = array_merge( $oldGroups, $toPromote );
1457 $logEntry->setPerformer( $this );
1459 $logEntry->setParameters( [
1460 '4::oldgroups' => $oldGroups,
1461 '5::newgroups' => $newGroups,
1463 $logid = $logEntry->insert();
1464 if ( $wgAutopromoteOnceLogInRC ) {
1465 $logEntry->publish( $logid );
1481 if ( $this->mTouched ) {
1483 $conditions[
'user_touched'] = $db->
timestamp( $this->mTouched );
1501 if ( !$this->mId ) {
1509 $dbw->update(
'user',
1510 [
'user_touched' => $dbw->timestamp( $newTouched ) ],
1512 'user_id' => $this->mId,
1516 $success = ( $dbw->affectedRows() > 0 );
1519 $this->mTouched = $newTouched;
1537 $this->mNewtalk = -1;
1538 $this->mDatePreference = null;
1539 $this->mBlockedby = -1; # Unset
1540 $this->mHash =
false;
1541 $this->mRights = null;
1542 $this->mEffectiveGroups = null;
1543 $this->mImplicitGroups = null;
1544 $this->mGroups = null;
1545 $this->mOptions = null;
1546 $this->mOptionsLoaded =
false;
1547 $this->mEditCount = null;
1549 if ( $reloadFrom ) {
1550 $this->mLoadedItems = [];
1551 $this->mFrom = $reloadFrom;
1564 static $defOpt = null;
1565 static $defOptLang = null;
1567 if ( $defOpt !== null && $defOptLang === $wgContLang->getCode() ) {
1576 $defOptLang = $wgContLang->getCode();
1577 $defOpt[
'language'] = $defOptLang;
1579 $defOpt[$langCode == $wgContLang->getCode() ?
'variant' :
"variant-$langCode"] = $langCode;
1581 $namespaces = MediaWikiServices::getInstance()->getSearchEngineConfig()->searchableNamespaces();
1583 $defOpt[
'searchNs' . $nsnum] = !empty( $wgNamespacesToBeSearchedDefault[$nsnum] );
1587 Hooks::run(
'UserGetDefaultOptions', [ &$defOpt ] );
1599 $defOpts = self::getDefaultOptions();
1600 if ( isset( $defOpts[$opt] ) ) {
1601 return $defOpts[$opt];
1616 if ( -1 != $this->mBlockedby ) {
1620 wfDebug( __METHOD__ .
": checking...\n" );
1629 # We only need to worry about passing the IP address to the Block generator if the
1630 # user is not immune to autoblocks/hardblocks, and they are the current user so we
1631 # know which IP address they're actually coming from
1633 if ( !$this->
isAllowed(
'ipblock-exempt' ) ) {
1636 $globalUserName = $wgUser->isSafeToLoad()
1637 ? $wgUser->getName()
1639 if ( $this->
getName() === $globalUserName ) {
1648 if ( !$block instanceof
Block && $ip !== null && !in_array( $ip, $wgProxyWhitelist ) ) {
1650 if ( self::isLocallyBlockedProxy( $ip ) ) {
1653 $block->mReason =
wfMessage(
'proxyblockreason' )->text();
1654 $block->setTarget( $ip );
1658 $block->mReason =
wfMessage(
'sorbsreason' )->text();
1659 $block->setTarget( $ip );
1664 if ( !$block instanceof
Block
1665 && $wgApplyIpBlocksToXff
1667 && !in_array( $ip, $wgProxyWhitelist )
1669 $xff = $this->
getRequest()->getHeader(
'X-Forwarded-For' );
1670 $xff = array_map(
'trim', explode(
',', $xff ) );
1671 $xff = array_diff( $xff, [ $ip ] );
1674 if ( $block instanceof
Block ) {
1675 # Mangle the reason to alert the user that the block
1676 # originated from matching the X-Forwarded-For header.
1677 $block->mReason =
wfMessage(
'xffblockreason', $block->mReason )->text();
1681 if ( $block instanceof
Block ) {
1682 wfDebug( __METHOD__ .
": Found block.\n" );
1683 $this->mBlock = $block;
1684 $this->mBlockedby = $block->getByName();
1685 $this->mBlockreason = $block->mReason;
1686 $this->mHideName = $block->mHideName;
1687 $this->mAllowUsertalk = !$block->prevents(
'editownusertalk' );
1689 $this->mBlockedby =
'';
1690 $this->mHideName = 0;
1691 $this->mAllowUsertalk =
false;
1695 Hooks::run(
'GetBlockedStatus', [ &$this ] );
1709 if ( !$wgEnableDnsBlacklist ) {
1713 if ( $checkWhitelist && in_array( $ip, $wgProxyWhitelist ) ) {
1733 $ipReversed = implode(
'.', array_reverse( explode(
'.', $ip ) ) );
1739 if ( is_array( $base ) ) {
1740 if ( count( $base ) >= 2 ) {
1742 $host =
"{$base[1]}.$ipReversed.{$base[0]}";
1744 $host =
"$ipReversed.{$base[0]}";
1746 $basename = $base[0];
1748 $host =
"$ipReversed.$base";
1752 $ipList = gethostbynamel( $host );
1755 wfDebugLog(
'dnsblacklist',
"Hostname $host is {$ipList[0]}, it's a proxy says $basename!" );
1759 wfDebugLog(
'dnsblacklist',
"Requested $host, not found in $basename." );
1777 if ( !$wgProxyList ) {
1781 if ( !is_array( $wgProxyList ) ) {
1783 $wgProxyList = array_map(
'trim',
file( $wgProxyList ) );
1786 if ( !is_array( $wgProxyList ) ) {
1788 } elseif ( array_search( $ip, $wgProxyList ) !==
false ) {
1790 } elseif ( array_key_exists( $ip, $wgProxyList ) ) {
1806 if ( in_array( $this->
getRequest()->getIP(), $wgRateLimitsExcludedIPs ) ) {
1812 return !$this->
isAllowed(
'noratelimit' );
1837 if ( !isset( $wgRateLimits[$action] ) ) {
1846 $limits = $wgRateLimits[$action];
1848 $id = $this->
getId();
1854 if ( isset( $limits[
'anon'] ) ) {
1855 $keys[
wfMemcKey(
'limiter', $action,
'anon' )] = $limits[
'anon'];
1859 if ( isset( $limits[
'user'] ) ) {
1860 $userLimit = $limits[
'user'];
1863 if ( $isNewbie && isset( $limits[
'newbie'] ) ) {
1864 $keys[
wfMemcKey(
'limiter', $action,
'user', $id )] = $limits[
'newbie'];
1871 if ( isset( $limits[
'ip'] ) ) {
1873 $keys[
"mediawiki:limiter:$action:ip:$ip"] = $limits[
'ip'];
1876 if ( isset( $limits[
'subnet'] ) ) {
1879 if ( $subnet !==
false ) {
1880 $keys[
"mediawiki:limiter:$action:subnet:$subnet"] = $limits[
'subnet'];
1888 if ( isset( $limits[$group] ) ) {
1889 if ( $userLimit ===
false
1890 || $limits[$group][0] / $limits[$group][1] > $userLimit[0] / $userLimit[1]
1892 $userLimit = $limits[$group];
1898 if ( $userLimit !==
false ) {
1899 list( $max, $period ) = $userLimit;
1900 wfDebug( __METHOD__ .
": effective user limit: $max in {$period}s\n" );
1901 $keys[
wfMemcKey(
'limiter', $action,
'user', $id )] = $userLimit;
1905 if ( isset( $limits[
'ip-all'] ) ) {
1908 if ( $isNewbie || $userLimit ===
false
1909 || $limits[
'ip-all'][0] / $limits[
'ip-all'][1] > $userLimit[0] / $userLimit[1] ) {
1910 $keys[
"mediawiki:limiter:$action:ip-all:$ip"] = $limits[
'ip-all'];
1915 if ( isset( $limits[
'subnet-all'] ) ) {
1918 if ( $subnet !==
false ) {
1920 if ( $isNewbie || $userLimit ===
false
1921 || $limits[
'ip-all'][0] / $limits[
'ip-all'][1]
1922 > $userLimit[0] / $userLimit[1] ) {
1923 $keys[
"mediawiki:limiter:$action:subnet-all:$subnet"] = $limits[
'subnet-all'];
1933 $summary =
"(limit $max in {$period}s)";
1938 wfDebugLog(
'ratelimit',
"User '{$this->getName()}' " .
1939 "(IP {$this->getRequest()->getIP()}) tripped $key at $count $summary" );
1942 wfDebug( __METHOD__ .
": ok. $key at $count $summary\n" );
1945 wfDebug( __METHOD__ .
": adding record for $key $summary\n" );
1947 $cache->add( $key, 0, intval( $period ) );
1977 return $this->mBlock instanceof
Block ? $this->mBlock : null;
1990 $blocked = $this->
isBlocked( $bFromSlave );
1991 $allowUsertalk = ( $wgBlockAllowsUTEdit ? $this->mAllowUsertalk :
false );
1993 if ( !$this->mHideName && $allowUsertalk &&
$title->getText() === $this->
getName()
1996 wfDebug( __METHOD__ .
": self-talk page, ignoring any blocks\n" );
1999 Hooks::run(
'UserIsBlockedFrom', [ $this,
$title, &$blocked, &$allowUsertalk ] );
2028 return ( $this->mBlock ? $this->mBlock->getId() :
false );
2054 if ( $this->mGlobalBlock !== null ) {
2055 return $this->mGlobalBlock ?: null;
2065 Hooks::run(
'UserIsBlockedGlobally', [ &$this, $ip, &$blocked, &$block ] );
2067 if ( $blocked && $block === null ) {
2073 $this->mGlobalBlock = $blocked ? $block :
false;
2074 return $this->mGlobalBlock ?: null;
2083 if ( $this->mLocked !== null ) {
2086 $authUser = AuthManager::callLegacyAuthPlugin(
'getUserInstance', [ &$this ], null );
2087 $this->mLocked = $authUser && $authUser->isLocked();
2088 Hooks::run(
'UserIsLocked', [ $this, &$this->mLocked ] );
2098 if ( $this->mHideName !== null ) {
2102 if ( !$this->mHideName ) {
2103 $authUser = AuthManager::callLegacyAuthPlugin(
'getUserInstance', [ &$this ], null );
2104 $this->mHideName = $authUser && $authUser->isHidden();
2105 Hooks::run(
'UserIsHidden', [ $this, &$this->mHideName ] );
2115 if ( $this->mId === null && $this->mName !== null &&
User::isIP( $this->mName ) ) {
2145 if ( $this->mName ===
false ) {
2168 $this->mName = $str;
2176 return str_replace(
' ',
'_', $this->
getName() );
2187 if ( $this->mNewtalk === -1 ) {
2188 $this->mNewtalk =
false; # reset talk
page status
2192 if ( !$this->mId ) {
2194 if ( $wgDisableAnonTalk ) {
2196 $this->mNewtalk =
false;
2201 $this->mNewtalk = $this->
checkNewtalk(
'user_id', $this->mId );
2223 if ( !
Hooks::run(
'UserRetrieveNewTalks', [ &$this, &$talks ] ) ) {
2232 'MIN(user_last_timestamp)',
2233 $this->
isAnon() ? [
'user_ip' => $this->
getName() ] : [
'user_id' => $this->
getId() ],
2236 return [ [
'wiki' =>
wfWikiID(),
'link' => $utp->getLocalURL(),
'rev' =>
$rev ] ];
2245 $newMessageRevisionId = null;
2247 if ( $newMessageLinks ) {
2251 if ( count( $newMessageLinks ) === 1
2252 && $newMessageLinks[0][
'wiki'] ===
wfWikiID()
2253 && $newMessageLinks[0][
'rev']
2256 $newMessageRevision = $newMessageLinks[0][
'rev'];
2257 $newMessageRevisionId = $newMessageRevision->getId();
2260 return $newMessageRevisionId;
2274 $ok =
$dbr->selectField(
'user_newtalk', $field, [ $field => $id ], __METHOD__ );
2276 return $ok !==
false;
2288 $prevRev = $curRev ? $curRev->getPrevious() :
false;
2289 $ts = $prevRev ? $prevRev->getTimestamp() : null;
2292 $dbw->insert(
'user_newtalk',
2293 [ $field => $id,
'user_last_timestamp' => $dbw->timestampOrNull( $ts ) ],
2296 if ( $dbw->affectedRows() ) {
2297 wfDebug( __METHOD__ .
": set on ($field, $id)\n" );
2300 wfDebug( __METHOD__ .
" already set ($field, $id)\n" );
2313 $dbw->delete(
'user_newtalk',
2316 if ( $dbw->affectedRows() ) {
2317 wfDebug( __METHOD__ .
": killed on ($field, $id)\n" );
2320 wfDebug( __METHOD__ .
": already gone ($field, $id)\n" );
2337 $this->mNewtalk = $val;
2344 $id = $this->
getId();
2367 if ( $this->mTouched && $time <= $this->mTouched ) {
2385 if ( !$this->
getId() ) {
2391 if ( $mode ===
'refresh' ) {
2392 $cache->delete( $key, 1 );
2425 $id = $this->
getId();
2427 $key =
wfMemcKey(
'user-quicktouched',
'id', $id );
2429 $this->mQuickTouched = null;
2454 if ( $this->mQuickTouched === null ) {
2455 $key =
wfMemcKey(
'user-quicktouched',
'id', $this->mId );
2461 return max( $this->mTouched, $this->mQuickTouched );
2484 throw new BadMethodCallException( __METHOD__ .
' has been removed in 1.27' );
2493 throw new BadMethodCallException( __METHOD__ .
' has been removed in 1.27' );
2515 if ( !$wgDisableAuthManager ) {
2519 if ( $str !== null ) {
2520 if ( !$wgAuth->allowPasswordChange() ) {
2530 if ( !$wgAuth->setPassword( $this, $str ) ) {
2534 $this->
setOption(
'watchlisttoken',
false );
2551 if ( !$wgDisableAuthManager ) {
2555 if ( $wgAuth->allowSetLocalPassword() ) {
2556 $this->
setOption(
'watchlisttoken',
false );
2572 if ( $wgDisableAuthManager ) {
2573 $id = self::idFromName( $this->
getName(), self::READ_LATEST );
2575 throw new LogicException(
'Cannot set a password for a user that is not in the database.' );
2584 'user_password' => $passwordFactory->newFromPlaintext( $str )->toString(),
2586 'user_newpass_time' => $dbw->timestampOrNull( null ),
2597 $manager = AuthManager::singleton();
2600 if ( !$manager->userExists( $this->getName() ) ) {
2601 throw new LogicException(
'Cannot set a password for a user that is not in the database.' );
2605 'username' => $this->
getName(),
2611 ->info( __METHOD__ .
': Password change rejected: '
2612 .
$status->getWikiText( null, null,
'en' ) );
2616 $this->
setOption(
'watchlisttoken',
false );
2619 SessionManager::singleton()->invalidateSessionsForUser( $this );
2638 if ( $wgDisableAuthManager ) {
2639 throw new LogicException( __METHOD__ .
' cannot be called when $wgDisableAuthManager '
2643 $manager = AuthManager::singleton();
2644 $reqs = $manager->getAuthenticationRequests( AuthManager::ACTION_CHANGE, $this );
2645 $reqs = AuthenticationRequest::loadRequestsFromSubmission( $reqs, $data );
2648 foreach ( $reqs
as $req ) {
2649 $status->merge( $manager->allowsAuthenticationDataChange( $req ),
true );
2651 if (
$status->getValue() ===
'ignored' ) {
2652 $status->warning(
'authenticationdatachange-ignored' );
2656 foreach ( $reqs
as $req ) {
2657 $manager->changeAuthenticationData( $req );
2673 if ( !$this->mToken && $forceCreation ) {
2677 if ( !$this->mToken ) {
2680 } elseif ( $this->mToken === self::INVALID_TOKEN ) {
2684 } elseif ( $wgAuthenticationTokenVersion === null ) {
2692 $len = max( 32, self::TOKEN_LENGTH );
2693 if ( strlen(
$ret ) < $len ) {
2695 throw new \UnexpectedValueException(
'Hmac returned less than 128 bits' );
2697 return substr(
$ret, -$len );
2709 if ( $this->mToken === self::INVALID_TOKEN ) {
2711 ->debug( __METHOD__ .
": Ignoring attempt to set token for system user \"$this\"" );
2712 } elseif ( !$token ) {
2715 $this->mToken = $token;
2730 if ( $wgDisableAuthManager ) {
2731 $id = $this->
getId();
2733 throw new LogicException(
'Cannot set new password for a user that is not in the database.' );
2741 'user_newpassword' => $passwordFactory->newFromPlaintext( $str )->toString(),
2744 if ( $str === null ) {
2745 $update[
'user_newpass_time'] = null;
2746 } elseif ( $throttle ) {
2747 $update[
'user_newpass_time'] = $dbw->timestamp();
2750 $dbw->update(
'user', $update, [
'user_id' => $id ], __METHOD__ );
2752 throw new BadMethodCallException( __METHOD__ .
' has been removed in 1.27' );
2765 if ( $wgDisableAuthManager ) {
2766 if ( !$wgPasswordReminderResendTime ) {
2772 $db = ( $this->queryFlagsUsed & self::READ_LATEST )
2775 $newpassTime = $db->selectField(
2777 'user_newpass_time',
2778 [
'user_id' => $this->
getId() ],
2782 if ( $newpassTime === null ) {
2785 $expiry =
wfTimestamp(
TS_UNIX, $newpassTime ) + $wgPasswordReminderResendTime * 3600;
2786 return time() < $expiry;
2788 throw new BadMethodCallException( __METHOD__ .
' has been removed in 1.27' );
2798 Hooks::run(
'UserGetEmail', [ $this, &$this->mEmail ] );
2808 Hooks::run(
'UserGetEmailAuthenticationTimestamp', [ $this, &$this->mEmailAuthenticated ] );
2818 if ( $str == $this->mEmail ) {
2822 $this->mEmail = $str;
2823 Hooks::run(
'UserSetEmail', [ $this, &$this->mEmail ] );
2836 if ( !$wgEnableEmail ) {
2841 if ( $str === $oldaddr ) {
2845 $type = $oldaddr !=
'' ?
'changed' :
'set';
2846 $notificationResult = null;
2848 if ( $wgEmailAuthentication ) {
2851 if (
$type ==
'changed' ) {
2852 $change = $str !=
'' ?
'changed' :
'removed';
2853 $notificationResult = $this->
sendMail(
2854 wfMessage(
'notificationemail_subject_' . $change )->
text(),
2855 wfMessage(
'notificationemail_body_' . $change,
2865 if ( $str !==
'' && $wgEmailAuthentication ) {
2869 if ( $notificationResult !== null ) {
2870 $result->merge( $notificationResult );
2902 $this->mRealName = $str;
2915 public function getOption( $oname, $defaultOverride = null, $ignoreHidden =
false ) {
2919 # We want 'disabled' preferences to always behave as the default value for
2920 # users, even if they have set the option explicitly in their settings (ie they
2921 # set it, and then it was disabled removing their ability to change it). But
2922 # we don't want to erase the preferences in the database in case the preference
2923 # is re-enabled again. So don't touch $mOptions, just override the returned value
2924 if ( !$ignoreHidden && in_array( $oname, $wgHiddenPrefs ) ) {
2925 return self::getDefaultOption( $oname );
2928 if ( array_key_exists( $oname, $this->mOptions ) ) {
2929 return $this->mOptions[$oname];
2931 return $defaultOverride;
2948 # We want 'disabled' preferences to always behave as the default value for
2949 # users, even if they have set the option explicitly in their settings (ie they
2950 # set it, and then it was disabled removing their ability to change it). But
2951 # we don't want to erase the preferences in the database in case the preference
2952 # is re-enabled again. So don't touch $mOptions, just override the returned value
2953 foreach ( $wgHiddenPrefs
as $pref ) {
2954 $default = self::getDefaultOption( $pref );
2955 if ( $default !== null ) {
2960 if (
$flags & self::GETOPTIONS_EXCLUDE_DEFAULTS ) {
2975 return (
bool)$this->
getOption( $oname );
2989 $val = $defaultOverride;
2991 return intval( $val );
3006 if ( is_null( $val ) ) {
3007 $val = self::getDefaultOption( $oname );
3010 $this->mOptions[$oname] = $val;
3026 $id = $this->
getId();
3027 if ( !$id || in_array( $oname, $wgHiddenPrefs ) ) {
3036 $token = hash_hmac(
'sha1',
"$oname:$id", $this->
getToken() );
3053 if ( in_array( $oname, $wgHiddenPrefs ) ) {
3088 'registered-multiselect',
3089 'registered-checkmatrix',
3121 unset( $prefs[
$name] );
3126 $multiselectOptions = [];
3127 foreach ( $prefs
as $name => $info ) {
3128 if ( ( isset( $info[
'type'] ) && $info[
'type'] ==
'multiselect' ) ||
3129 ( isset( $info[
'class'] ) && $info[
'class'] ==
'HTMLMultiSelectField' ) ) {
3131 $prefix = isset( $info[
'prefix'] ) ? $info[
'prefix'] :
$name;
3134 $multiselectOptions[
"$prefix$value"] =
true;
3137 unset( $prefs[
$name] );
3140 $checkmatrixOptions = [];
3141 foreach ( $prefs
as $name => $info ) {
3142 if ( ( isset( $info[
'type'] ) && $info[
'type'] ==
'checkmatrix' ) ||
3143 ( isset( $info[
'class'] ) && $info[
'class'] ==
'HTMLCheckMatrix' ) ) {
3146 $prefix = isset( $info[
'prefix'] ) ? $info[
'prefix'] :
$name;
3148 foreach ( $columns
as $column ) {
3149 foreach ( $rows
as $row ) {
3150 $checkmatrixOptions[
"$prefix$column-$row"] =
true;
3154 unset( $prefs[
$name] );
3160 if ( isset( $prefs[$key] ) ) {
3161 $mapping[$key] =
'registered';
3162 } elseif ( isset( $multiselectOptions[$key] ) ) {
3163 $mapping[$key] =
'registered-multiselect';
3164 } elseif ( isset( $checkmatrixOptions[$key] ) ) {
3165 $mapping[$key] =
'registered-checkmatrix';
3166 } elseif ( isset( $specialOptions[$key] ) ) {
3167 $mapping[$key] =
'special';
3168 } elseif ( substr( $key, 0, 7 ) ===
'userjs-' ) {
3169 $mapping[$key] =
'userjs';
3171 $mapping[$key] =
'unused';
3193 $resetKinds = [
'registered',
'registered-multiselect',
'registered-checkmatrix',
'unused' ],
3197 $defaultOptions = self::getDefaultOptions();
3199 if ( !is_array( $resetKinds ) ) {
3200 $resetKinds = [ $resetKinds ];
3203 if ( in_array(
'all', $resetKinds ) ) {
3204 $newOptions = $defaultOptions;
3211 $resetKinds = array_intersect( $resetKinds, self::listOptionKinds() );
3216 foreach ( $this->mOptions
as $key =>
$value ) {
3217 if ( in_array( $optionKinds[$key], $resetKinds ) ) {
3218 if ( array_key_exists( $key, $defaultOptions ) ) {
3219 $newOptions[$key] = $defaultOptions[$key];
3222 $newOptions[$key] =
$value;
3227 Hooks::run(
'UserResetAllOptions', [ $this, &$newOptions, $this->mOptions, $resetKinds ] );
3229 $this->mOptions = $newOptions;
3230 $this->mOptionsLoaded =
true;
3239 if ( is_null( $this->mDatePreference ) ) {
3242 $map = $wgLang->getDatePreferenceMigrationMap();
3243 if ( isset( $map[
$value] ) ) {
3246 $this->mDatePreference =
$value;
3259 if ( !$wgSecureLogin ) {
3263 Hooks::run(
'UserRequiresHTTPS', [ $this, &$https ] );
3279 if ( $threshold > $wgMaxArticleSize * 1024 ) {
3292 if ( is_null( $this->mRights ) ) {
3297 if ( !defined(
'MW_NO_SESSION' ) ) {
3298 $allowedRights = $this->
getRequest()->getSession()->getAllowedUserRights();
3299 if ( $allowedRights !== null ) {
3300 $this->mRights = array_intersect( $this->mRights, $allowedRights );
3304 Hooks::run(
'UserGetRights', [ $this, &$this->mRights ] );
3306 $this->mRights = array_values( array_unique( $this->mRights ) );
3330 if ( $recache || is_null( $this->mEffectiveGroups ) ) {
3331 $this->mEffectiveGroups = array_unique( array_merge(
3336 Hooks::run(
'UserEffectiveGroups', [ &$this, &$this->mEffectiveGroups ] );
3338 $this->mEffectiveGroups = array_values( array_unique( $this->mEffectiveGroups ) );
3351 if ( $recache || is_null( $this->mImplicitGroups ) ) {
3352 $this->mImplicitGroups = [
'*' ];
3353 if ( $this->
getId() ) {
3354 $this->mImplicitGroups[] =
'user';
3356 $this->mImplicitGroups = array_unique( array_merge(
3357 $this->mImplicitGroups,
3364 $this->mEffectiveGroups = null;
3382 if ( is_null( $this->mFormerGroups ) ) {
3383 $db = ( $this->queryFlagsUsed & self::READ_LATEST )
3386 $res = $db->select(
'user_former_groups',
3388 [
'ufg_user' => $this->mId ],
3390 $this->mFormerGroups = [];
3391 foreach (
$res as $row ) {
3392 $this->mFormerGroups[] = $row->ufg_group;
3404 if ( !$this->
getId() ) {
3408 if ( $this->mEditCount === null ) {
3413 'user',
'user_editcount',
3414 [
'user_id' => $this->mId ],
3422 $this->mEditCount =
$count;
3436 if ( !
Hooks::run(
'UserAddGroup', [ $this, &$group ] ) ) {
3441 if ( $this->
getId() ) {
3442 $dbw->insert(
'user_groups',
3444 'ug_user' => $this->
getId(),
3445 'ug_group' => $group,
3452 $this->mGroups[] = $group;
3455 $this->mGroups = array_unique( $this->mGroups );
3460 $this->mRights = null;
3475 if ( !
Hooks::run(
'UserRemoveGroup', [ $this, &$group ] ) ) {
3480 $dbw->delete(
'user_groups',
3482 'ug_user' => $this->
getId(),
3483 'ug_group' => $group,
3487 $dbw->insert(
'user_former_groups',
3489 'ufg_user' => $this->
getId(),
3490 'ufg_group' => $group,
3497 $this->mGroups = array_diff( $this->mGroups, [ $group ] );
3502 $this->mRights = null;
3514 return $this->
getId() != 0;
3535 Hooks::run(
"UserIsBot", [ $this, &$isBot ] );
3547 $permissions = func_get_args();
3548 foreach ( $permissions
as $permission ) {
3549 if ( $this->
isAllowed( $permission ) ) {
3562 $permissions = func_get_args();
3563 foreach ( $permissions
as $permission ) {
3564 if ( !$this->
isAllowed( $permission ) ) {
3577 if ( $action ===
'' ) {
3582 return in_array( $action, $this->
getRights(),
true );
3591 return $wgUseRCPatrol && $this->
isAllowedAny(
'patrol',
'patrolmarks' );
3601 ( $wgUseRCPatrol || $wgUseNPPatrol )
3613 ( $wgUseRCPatrol || $wgUseFilePatrol )
3624 if ( $this->mRequest ) {
3641 if (
$title->isWatchable() && ( !$checkRights || $this->
isAllowed(
'viewmywatchlist' ) ) ) {
3642 return MediaWikiServices::getInstance()->getWatchedItemStore()->isWatched( $this,
$title );
3655 if ( !$checkRights || $this->
isAllowed(
'editmywatchlist' ) ) {
3656 MediaWikiServices::getInstance()->getWatchedItemStore()->addWatchBatchForUser(
3672 if ( !$checkRights || $this->
isAllowed(
'editmywatchlist' ) ) {
3673 $store = MediaWikiServices::getInstance()->getWatchedItemStore();
3674 $store->removeWatch( $this,
$title->getSubjectPage() );
3675 $store->removeWatch( $this,
$title->getTalkPage() );
3697 if ( !$this->
isAllowed(
'editmywatchlist' ) ) {
3703 if ( !
Hooks::run(
'UserClearNewTalkNotification', [ &$this, $oldid ] ) ) {
3726 if ( !$wgUseEnotif && !$wgShowUpdatedMarker ) {
3744 MediaWikiServices::getInstance()->getWatchedItemStore()
3745 ->resetNotificationTimestamp( $this,
$title, $force, $oldid );
3760 if ( !$this->
isAllowed(
'editmywatchlist' ) ) {
3765 if ( !$wgUseEnotif && !$wgShowUpdatedMarker ) {
3769 $id = $this->
getId();
3772 $dbw->update(
'watchlist',
3773 [
'wl_notificationtimestamp' => null ],
3774 [
'wl_user' => $id,
'wl_notificationtimestamp IS NOT NULL' ],
3845 $exp += $wgExtendedLoginCookieExpiration !== null
3846 ? $wgExtendedLoginCookieExpiration
3862 if ( 0 == $this->mId ) {
3866 $session = $this->
getRequest()->getSession();
3868 $session = $session->sessionWithRequest(
$request );
3870 $delay = $session->delaySave();
3872 if ( !$session->getUser()->equals( $this ) ) {
3873 if ( !$session->canSetUser() ) {
3875 ->warning( __METHOD__ .
3876 ": Cannot save user \"$this\" to a user \"{$session->getUser()}\"'s immutable session"
3880 $session->setUser( $this );
3883 $session->setRememberUser( $rememberMe );
3884 if ( $secure !== null ) {
3885 $session->setForceHTTPS( $secure );
3888 $session->persist();
3897 if (
Hooks::run(
'UserLogout', [ &$this ] ) ) {
3907 $session = $this->
getRequest()->getSession();
3908 if ( !$session->canSetUser() ) {
3910 ->warning( __METHOD__ .
": Cannot log out of an immutable session" );
3911 $error =
'immutable';
3912 } elseif ( !$session->getUser()->equals( $this ) ) {
3914 ->warning( __METHOD__ .
3915 ": Cannot log user \"$this\" out of a user \"{$session->getUser()}\"'s session"
3919 $error =
'wronguser';
3922 $delay = $session->delaySave();
3923 $session->unpersist();
3924 $session->setLoggedOutTimestamp( time() );
3925 $session->setUser(
new User );
3926 $session->set(
'wsUserID', 0 );
3927 $session->resetAllTokens();
3932 'event' =>
'logout',
3933 'successful' => $error ===
false,
3934 'status' => $error ?:
'success',
3948 "Could not update user with ID '{$this->mId}'; DB is read-only."
3954 if ( 0 == $this->mId ) {
3964 $dbw->update(
'user',
3966 'user_name' => $this->mName,
3967 'user_real_name' => $this->mRealName,
3968 'user_email' => $this->mEmail,
3969 'user_email_authenticated' => $dbw->timestampOrNull( $this->mEmailAuthenticated ),
3970 'user_touched' => $dbw->timestamp( $newTouched ),
3971 'user_token' => strval( $this->mToken ),
3973 'user_email_token_expires' => $dbw->timestampOrNull( $this->mEmailTokenExpires ),
3975 'user_id' => $this->mId,
3979 if ( !$dbw->affectedRows() ) {
3983 $from = ( $this->queryFlagsUsed & self::READ_LATEST ) ?
'master' :
'slave';
3985 "CAS update failed on user_touched for user ID '{$this->mId}' (read from $from);" .
3986 " the version of the user to be saved is older than the current version."
3990 $this->mTouched = $newTouched;
4010 $db = ( (
$flags & self::READ_LATEST ) == self::READ_LATEST )
4014 $options = ( (
$flags & self::READ_LOCKING ) == self::READ_LOCKING )
4015 ? [
'LOCK IN SHARE MODE' ]
4018 $id = $db->selectField(
'user',
4019 'user_id', [
'user_name' =>
$s ], __METHOD__,
$options );
4040 foreach ( [
'password',
'newpassword',
'newpass_time',
'password_expires' ]
as $field ) {
4041 if ( isset(
$params[$field] ) ) {
4042 wfDeprecated( __METHOD__ .
" with param '$field'",
'1.27' );
4050 if ( isset(
$params[
'options'] ) ) {
4055 $seqVal = $dbw->nextSequenceValue(
'user_user_id_seq' );
4060 'user_id' => $seqVal,
4061 'user_name' =>
$name,
4062 'user_password' => $noPass,
4063 'user_newpassword' => $noPass,
4064 'user_email' =>
$user->mEmail,
4065 'user_email_authenticated' => $dbw->timestampOrNull(
$user->mEmailAuthenticated ),
4066 'user_real_name' =>
$user->mRealName,
4067 'user_token' => strval(
$user->mToken ),
4068 'user_registration' => $dbw->timestamp(
$user->mRegistration ),
4069 'user_editcount' => 0,
4070 'user_touched' => $dbw->timestamp(
$user->newTouchedTimestamp() ),
4073 $fields[
"user_$name"] =
$value;
4075 $dbw->insert(
'user', $fields, __METHOD__, [
'IGNORE' ] );
4076 if ( $dbw->affectedRows() ) {
4112 if ( !$this->mToken ) {
4121 $inWrite = $dbw->writesOrCallbacksPending();
4122 $seqVal = $dbw->nextSequenceValue(
'user_user_id_seq' );
4123 $dbw->insert(
'user',
4125 'user_id' => $seqVal,
4126 'user_name' => $this->mName,
4127 'user_password' => $noPass,
4128 'user_newpassword' => $noPass,
4129 'user_email' => $this->mEmail,
4130 'user_email_authenticated' => $dbw->timestampOrNull( $this->mEmailAuthenticated ),
4132 'user_token' => strval( $this->mToken ),
4133 'user_registration' => $dbw->timestamp( $this->mRegistration ),
4134 'user_editcount' => 0,
4135 'user_touched' => $dbw->timestamp( $this->mTouched ),
4139 if ( !$dbw->affectedRows() ) {
4145 $options = [
'LOCK IN SHARE MODE' ];
4146 $flags = self::READ_LOCKING;
4150 $dbw->commit( __METHOD__,
'flush' );
4152 $flags = self::READ_LATEST;
4154 $this->mId = $dbw->selectField(
'user',
'user_id',
4155 [
'user_name' => $this->mName ], __METHOD__,
$options );
4163 throw new MWException( __METHOD__ .
": hit a key conflict attempting " .
4164 "to insert user '{$this->mName}' row, but it was not present in select!" );
4168 $this->mId = $dbw->insertId();
4197 wfDebug( __METHOD__ .
"()\n" );
4199 if ( $this->mId == 0 ) {
4204 if ( !$userblock ) {
4208 return (
bool)$userblock->doAutoblock( $this->
getRequest()->getIP() );
4217 if ( $this->mBlock && $this->mBlock->prevents(
'createaccount' ) ) {
4221 # bug 13611: if the IP address the user is trying to create an account from is
4222 # blocked with createaccount disabled, prevent new account creation there even
4223 # when the user is logged in
4224 if ( $this->mBlockedFromCreateAccount ===
false && !$this->
isAllowed(
'ipblock-exempt' ) ) {
4227 return $this->mBlockedFromCreateAccount instanceof
Block
4228 && $this->mBlockedFromCreateAccount->
prevents(
'createaccount' )
4229 ? $this->mBlockedFromCreateAccount
4239 return $this->mBlock && $this->mBlock->prevents(
'sendemail' );
4266 return $title->getTalkPage();
4275 return !$this->
isAllowed(
'autoconfirmed' );
4287 if ( $wgDisableAuthManager ) {
4300 if ( $wgAuth->authenticate( $this->getName(), $password ) ) {
4302 } elseif ( $wgAuth->strict() ) {
4305 } elseif ( $wgAuth->strictUserAuth( $this->getName() ) ) {
4312 $db = ( $this->queryFlagsUsed & self::READ_LATEST )
4317 $mPassword = $passwordFactory->newFromCiphertext( $db->selectField(
4318 'user',
'user_password', [
'user_id' => $this->getId() ], __METHOD__
4321 wfDebug(
'Invalid password hash found in database.' );
4325 if ( !$mPassword->equals( $password ) ) {
4326 if ( $wgLegacyEncoding ) {
4329 $cp1252Password = iconv(
'UTF-8',
'WINDOWS-1252//TRANSLIT', $password );
4330 if ( $cp1252Password === $password || !$mPassword->equals( $cp1252Password ) ) {
4338 if ( $passwordFactory->needsUpdate( $mPassword ) && !
wfReadOnly() ) {
4344 $manager = AuthManager::singleton();
4345 $reqs = AuthenticationRequest::loadRequestsFromSubmission(
4346 $manager->getAuthenticationRequests( AuthManager::ACTION_LOGIN ),
4348 'username' => $this->
getName(),
4349 'password' => $password,
4352 $res = AuthManager::singleton()->beginAuthentication( $reqs,
'null:' );
4353 switch ( $res->status ) {
4354 case AuthenticationResponse::PASS:
4356 case AuthenticationResponse::FAIL:
4359 ->info( __METHOD__ .
': Authentication failed: ' . $res->message->plain() );
4362 throw new BadMethodCallException(
4363 'AuthManager returned a response unsupported by ' . __METHOD__
4380 if ( $wgDisableAuthManager ) {
4385 $db = ( $this->queryFlagsUsed & self::READ_LATEST )
4389 $row = $db->selectRow(
4391 [
'user_newpassword',
'user_newpass_time' ],
4392 [
'user_id' => $this->
getId() ],
4396 $newPassword = $passwordFactory->newFromCiphertext( $row->user_newpassword );
4398 wfDebug(
'Invalid password hash found in database.' );
4402 if ( $newPassword->equals( $plaintext ) ) {
4403 if ( is_null( $row->user_newpass_time ) ) {
4407 return ( time() < $expiry );
4436 return $request->getSession()->getToken( $salt );
4492 $val = substr( $val, 0, strspn( $val,
'0123456789abcdef' ) ) . Token::SUFFIX;
4511 if (
$type ==
'created' ||
$type ===
false ) {
4512 $message =
'confirmemail_body';
4513 } elseif (
$type ===
true ) {
4514 $message =
'confirmemail_body_changed';
4517 $message =
'confirmemail_body_' .
$type;
4525 $wgLang->userTimeAndDate( $expiration, $this ),
4527 $wgLang->userDate( $expiration, $this ),
4528 $wgLang->userTime( $expiration, $this ) )->
text() );
4554 'replyTo' => $replyto,
4575 $hash = md5( $token );
4576 $this->mEmailToken = $hash;
4577 $this->mEmailTokenExpires = $expiration;
4587 return $this->
getTokenUrl(
'ConfirmEmail', $token );
4596 return $this->
getTokenUrl(
'InvalidateEmail', $token );
4616 return $title->getCanonicalURL();
4631 Hooks::run(
'ConfirmEmailComplete', [ $this ] );
4645 $this->mEmailToken = null;
4646 $this->mEmailTokenExpires = null;
4649 Hooks::run(
'InvalidateEmailComplete', [ $this ] );
4660 Hooks::run(
'UserSetEmailAuthenticationTimestamp', [ $this, &$this->mEmailAuthenticated ] );
4670 if ( !$wgEnableEmail || !$wgEnableUserEmail || !$this->
isAllowed(
'sendemail' ) ) {
4674 Hooks::run(
'UserCanSendEmail', [ &$this, &$canSend ] );
4701 if (
Hooks::run(
'EmailConfirmed', [ &$this, &$confirmed ] ) ) {
4723 return $wgEmailAuthentication &&
4725 $this->mEmailToken &&
4751 if ( $this->
getId() == 0 ) {
4755 $time =
$dbr->selectField(
'revision',
'rev_timestamp',
4756 [
'rev_user' => $this->
getId() ],
4758 [
'ORDER BY' =>
'rev_timestamp ASC' ]
4776 foreach ( $groups
as $group ) {
4777 if ( isset( $wgGroupPermissions[$group] ) ) {
4778 $rights = array_merge( $rights,
4780 array_keys( array_filter( $wgGroupPermissions[$group] ) ) );
4784 foreach ( $groups
as $group ) {
4785 if ( isset( $wgRevokePermissions[$group] ) ) {
4786 $rights = array_diff( $rights,
4787 array_keys( array_filter( $wgRevokePermissions[$group] ) ) );
4790 return array_unique( $rights );
4801 $allowedGroups = [];
4802 foreach ( array_keys( $wgGroupPermissions )
as $group ) {
4803 if ( self::groupHasPermission( $group, $role ) ) {
4804 $allowedGroups[] = $group;
4807 return $allowedGroups;
4824 return isset( $wgGroupPermissions[$group][$role] ) && $wgGroupPermissions[$group][$role]
4825 && !( isset( $wgRevokePermissions[$group][$role] ) && $wgRevokePermissions[$group][$role] );
4848 if ( isset(
$cache[$right] ) && !defined(
'MW_PHPUNIT_TEST' ) ) {
4852 if ( !isset( $wgGroupPermissions[
'*'][$right] ) || !$wgGroupPermissions[
'*'][$right] ) {
4858 foreach ( $wgRevokePermissions
as $rights ) {
4859 if ( isset( $rights[$right] ) && $rights[$right] ) {
4867 if ( !defined(
'MW_NO_SESSION' ) ) {
4868 $allowedRights = SessionManager::getGlobalSession()->getAllowedUserRights();
4869 if ( $allowedRights !== null && !in_array( $right, $allowedRights,
true ) ) {
4876 if ( !
Hooks::run(
'UserIsEveryoneAllowed', [ $right ] ) ) {
4893 return $msg->isBlank() ? $group : $msg->text();
4905 return $msg->isBlank() ? $group : $msg->text();
4917 array_merge( array_keys( $wgGroupPermissions ), array_keys( $wgRevokePermissions ) ),
4918 self::getImplicitGroups()
4927 if ( self::$mAllRights ===
false ) {
4929 if ( count( $wgAvailableRights ) ) {
4930 self::$mAllRights = array_unique( array_merge( self::$mCoreRights, $wgAvailableRights ) );
4932 self::$mAllRights = self::$mCoreRights;
4934 Hooks::run(
'UserGetAllRights', [ &self::$mAllRights ] );
4936 return self::$mAllRights;
4947 # Deprecated, use $wgImplicitGroups instead
4948 Hooks::run(
'UserGetImplicitGroups', [ &$groups ],
'1.25' );
4960 $msg =
wfMessage(
'grouppage-' . $group )->inContentLanguage();
4961 if ( $msg->exists() ) {
4963 if ( is_object(
$title ) ) {
4979 if ( $text ==
'' ) {
4980 $text = self::getGroupName( $group );
4982 $title = self::getGroupPage( $group );
4986 return htmlspecialchars( $text );
4999 if ( $text ==
'' ) {
5000 $text = self::getGroupName( $group );
5002 $title = self::getGroupPage( $group );
5005 return "[[$page|$text]]";
5030 if ( empty( $wgAddGroups[$group] ) ) {
5032 } elseif ( $wgAddGroups[$group] ===
true ) {
5034 $groups[
'add'] = self::getAllGroups();
5035 } elseif ( is_array( $wgAddGroups[$group] ) ) {
5036 $groups[
'add'] = $wgAddGroups[$group];
5040 if ( empty( $wgRemoveGroups[$group] ) ) {
5042 } elseif ( $wgRemoveGroups[$group] ===
true ) {
5043 $groups[
'remove'] = self::getAllGroups();
5044 } elseif ( is_array( $wgRemoveGroups[$group] ) ) {
5045 $groups[
'remove'] = $wgRemoveGroups[$group];
5049 if ( empty( $wgGroupsAddToSelf[
'user'] ) || $wgGroupsAddToSelf[
'user'] !==
true ) {
5050 foreach ( $wgGroupsAddToSelf
as $key =>
$value ) {
5051 if ( is_int( $key ) ) {
5052 $wgGroupsAddToSelf[
'user'][] =
$value;
5057 if ( empty( $wgGroupsRemoveFromSelf[
'user'] ) || $wgGroupsRemoveFromSelf[
'user'] !==
true ) {
5058 foreach ( $wgGroupsRemoveFromSelf
as $key =>
$value ) {
5059 if ( is_int( $key ) ) {
5060 $wgGroupsRemoveFromSelf[
'user'][] =
$value;
5066 if ( empty( $wgGroupsAddToSelf[$group] ) ) {
5068 } elseif ( $wgGroupsAddToSelf[$group] ===
true ) {
5071 } elseif ( is_array( $wgGroupsAddToSelf[$group] ) ) {
5072 $groups[
'add-self'] = $wgGroupsAddToSelf[$group];
5075 if ( empty( $wgGroupsRemoveFromSelf[$group] ) ) {
5077 } elseif ( $wgGroupsRemoveFromSelf[$group] ===
true ) {
5079 } elseif ( is_array( $wgGroupsRemoveFromSelf[$group] ) ) {
5080 $groups[
'remove-self'] = $wgGroupsRemoveFromSelf[$group];
5094 if ( $this->
isAllowed(
'userrights' ) ) {
5117 foreach ( $addergroups
as $addergroup ) {
5118 $groups = array_merge_recursive(
5121 $groups[
'add'] = array_unique( $groups[
'add'] );
5122 $groups[
'remove'] = array_unique( $groups[
'remove'] );
5123 $groups[
'add-self'] = array_unique( $groups[
'add-self'] );
5124 $groups[
'remove-self'] = array_unique( $groups[
'remove-self'] );
5152 [
'user_editcount=user_editcount+1' ],
5153 [
'user_id' => $this->
getId(),
'user_editcount IS NOT NULL' ],
5157 if ( $dbw->affectedRows() == 0 ) {
5160 if (
$dbr !== $dbw ) {
5189 [
'rev_user' => $this->getId() ],
5197 [
'user_editcount' =>
$count ],
5198 [
'user_id' => $this->
getId() ],
5212 $key =
"right-$right";
5214 return $msg->isBlank() ? $right : $msg->text();
5226 public static function crypt( $password, $salt =
false ) {
5230 $hash = $passwordFactory->newFromPlaintext( $password );
5231 return $hash->toString();
5250 if ( preg_match(
'/^[0-9a-f]{32}$/', $hash ) ) {
5252 if ( $wgPasswordSalt ) {
5253 $password =
":B:{$userId}:{$hash}";
5255 $password =
":A:{$hash}";
5261 $hash = $passwordFactory->newFromCiphertext( $hash );
5262 return $hash->equals( $password );
5288 if ( !$wgDisableAuthManager || empty( $wgNewUserLog ) ) {
5292 if ( $action ===
true ) {
5293 $action =
'byemail';
5294 } elseif ( $action ===
false ) {
5295 if ( $this->
equals( $wgUser ) ) {
5298 $action =
'create2';
5302 if ( $action ===
'create' || $action ===
'autocreate' ) {
5309 $logEntry->setPerformer( $performer );
5311 $logEntry->setComment( $reason );
5312 $logEntry->setParameters( [
5313 '4::userid' => $this->
getId(),
5315 $logid = $logEntry->insert();
5317 if ( $action !==
'autocreate' ) {
5318 $logEntry->publish( $logid );
5348 if ( $this->mOptionsLoaded ) {
5352 $this->mOptions = self::getDefaultOptions();
5354 if ( !$this->
getId() ) {
5359 $variant = $wgContLang->getDefaultVariant();
5360 $this->mOptions[
'variant'] = $variant;
5361 $this->mOptions[
'language'] = $variant;
5362 $this->mOptionsLoaded =
true;
5367 if ( !is_null( $this->mOptionOverrides ) ) {
5368 wfDebug(
"User: loading options for user " . $this->
getId() .
" from override cache.\n" );
5369 foreach ( $this->mOptionOverrides
as $key =>
$value ) {
5370 $this->mOptions[$key] =
$value;
5373 if ( !is_array( $data ) ) {
5374 wfDebug(
"User: loading options for user " . $this->
getId() .
" from database.\n" );
5376 $dbr = ( $this->queryFlagsUsed & self::READ_LATEST )
5382 [
'up_property',
'up_value' ],
5383 [
'up_user' => $this->
getId() ],
5387 $this->mOptionOverrides = [];
5389 foreach (
$res as $row ) {
5390 $data[$row->up_property] = $row->up_value;
5399 $this->mOptionsLoaded =
true;
5401 Hooks::run(
'UserLoadOptions', [ $this, &$this->mOptions ] );
5417 if ( !
Hooks::run(
'UserSaveOptions', [ $this, &$saveOptions ] ) ) {
5421 $userId = $this->
getId();
5424 foreach ( $saveOptions
as $key =>
$value ) {
5426 $defaultOption = self::getDefaultOption( $key );
5427 if ( ( $defaultOption === null &&
$value !==
false &&
$value !== null )
5428 ||
$value != $defaultOption
5431 'up_user' => $userId,
5432 'up_property' => $key,
5440 $res = $dbw->select(
'user_properties',
5441 [
'up_property',
'up_value' ], [
'up_user' => $userId ], __METHOD__ );
5446 foreach (
$res as $row ) {
5447 if ( !isset( $saveOptions[$row->up_property] )
5448 || strcmp( $saveOptions[$row->up_property], $row->up_value ) != 0
5450 $keysDelete[] = $row->up_property;
5454 if ( count( $keysDelete ) ) {
5462 $dbw->delete(
'user_properties',
5463 [
'up_user' => $userId,
'up_property' => $keysDelete ], __METHOD__ );
5466 $dbw->insert(
'user_properties', $insert_rows, __METHOD__, [
'IGNORE' ] );
5509 if ( $wgMinimalPasswordLength == 0 ) {
5513 # Note that the pattern requirement will always be satisfied if the
5514 # input is empty, so we need required in all cases.
5516 # @todo FIXME: Bug 23769: This needs to not claim the password is required
5517 # if e-mail confirmation is being used. Since HTML5 input validation
5518 # is b0rked anyway in some browsers, just return nothing. When it's
5519 # re-enabled, fix this code to not output required for e-mail
5521 # $ret = array( 'required' );
5524 # We can't actually do this right now, because Opera 9.6 will print out
5525 # the entered password visibly in its error message! When other
5526 # browsers add support for this attribute, or Opera fixes its support,
5527 # we can add support with a version check to avoid doing this on Opera
5528 # versions where it will be a problem. Reported to Opera as
5529 # DSK-262266, but they don't have a public bug tracker for us to follow.
5554 'user_email_authenticated',
5556 'user_email_token_expires',
5557 'user_registration',
5572 $groups = array_map(
5573 [
'User',
'makeGroupLinkWiki' ],
5578 return Status::newFatal(
'badaccess-groups', $wgLang->commaList( $groups ), count( $groups ) );
5594 if ( !$this->
getId() ) {
5599 if ( !
$user->loadFromId( self::READ_EXCLUSIVE ) ) {
static newFromName($name, $validate= 'valid')
Static factory method for creation from username.
addAutopromoteOnceGroups($event)
Add the user to the group if he/she meets given criteria.
getEmail()
Get the user's e-mail address.
static randomPassword()
Return a random password.
$wgUserEmailConfirmationTokenExpiry
The time, in seconds, when an email confirmation email expires.
isHidden()
Check if user account is hidden.
string null $wgAuthenticationTokenVersion
Versioning for authentication tokens.
Factory class for creating and checking Password objects.
static whoIs($id)
Get the username corresponding to a given user ID.
const VERSION
int Serialized record version.
static getMainWANInstance()
Get the main WAN cache object.
setBlocker($user)
Set the user who implemented (or will implement) this block.
$wgNewUserLog
Maintain a log of newusers at Log/newusers?
Interface for objects which can provide a MediaWiki context on request.
deferred txt A few of the database updates required by various functions here can be deferred until after the result page is displayed to the user For updating the view updating the linked to tables after a etc PHP does not yet have any way to tell the server to actually return and disconnect while still running these but it might have such a feature in the future We handle these by creating a deferred update object and putting those objects on a global list
isPasswordReminderThrottled()
Has password reminder email been sent within the last $wgPasswordReminderResendTime hours...
static newFromRow($row, $data=null)
Create a new user object from a user row.
wfGetDB($db, $groups=[], $wiki=false)
Get a Database object.
$wgMaxArticleSize
Maximum article size in kilobytes.
getBoolOption($oname)
Get the user's current setting for a given option, as a boolean value.
getNewMessageLinks()
Return the data needed to construct links for new talk page message alerts.
the array() calling protocol came about after MediaWiki 1.4rc1.
isNewbie()
Determine whether the user is a newbie.
static whoIsReal($id)
Get the real name of a user given their user ID.
wfCanIPUseHTTPS($ip)
Determine whether the client at a given source IP is likely to be able to access the wiki via HTTPS...
matchEditTokenNoSuffix($val, $salt= '', $request=null, $maxage=null)
Check given value against the token value stored in the session, ignoring the suffix.
static sanitizeIP($ip)
Convert an IP into a verbose, uppercase, normalized form.
static getEditTokenTimestamp($val)
Get the embedded timestamp from a token.
isBlockedFrom($title, $bFromSlave=false)
Check if user is blocked from editing a particular article.
checkPassword($password)
Check to see if the given clear-text password is one of the accepted passwords.
static chooseBlock(array $blocks, array $ipChain)
From a list of multiple blocks, find the most exact and strongest Block.
$wgMaxNameChars
Maximum number of bytes in username.
clearInstanceCache($reloadFrom=false)
Clear various cached data stored in this object.
$wgDefaultUserOptions
Settings added to this array will override the default globals for the user preferences used by anony...
loadFromSession()
Load user data from the session.
isAllowedToCreateAccount()
Get whether the user is allowed to create an account.
Block $mBlockedFromCreateAccount
isValidPassword($password)
Is the input a valid password for this user?
logout()
Log this user out.
clearNotification(&$title, $oldid=0)
Clear the user's notification timestamp for the given title.
isDnsBlacklisted($ip, $checkWhitelist=false)
Whether the given IP is in a DNS blacklist.
static getImplicitGroups()
Get a list of implicit groups.
saveSettings()
Save this user's settings into the database.
processing should stop and the error should be shown to the user * false
static isLocallyBlockedProxy($ip)
Check if an IP address is in the local proxy list.
load($flags=self::READ_NORMAL)
Load the user table data for this object from the source given by mFrom.
getFirstEditTimestamp()
Get the timestamp of the first edit.
static $mCoreRights
Array of Strings Core rights.
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for use
const GETOPTIONS_EXCLUDE_DEFAULTS
Exclude user options that are set to their default value.
isAllowedAny()
Check if user is allowed to access a feature / make an action.
isBlockedFromEmailuser()
Get whether the user is blocked from using Special:Emailuser.
static getCanonicalName($name, $validate= 'valid')
Given unvalidated user input, return a canonical username, or false if the username is invalid...
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException'returning false will NOT prevent logging $e
setCookie($name, $value, $exp=0, $secure=null, $params=[], $request=null)
Set a cookie on the user's client.
getAutomaticGroups($recache=false)
Get the list of implicit group memberships this user has.
pingLimiter($action= 'edit', $incrBy=1)
Primitive rate limits: enforce maximum actions per time period to put a brake on flooding.
const TOKEN_LENGTH
int Number of characters in user_token field.
clearSharedCache($mode= 'changed')
Clear user data from memcached.
loadFromUserObject($user)
Load the data for this user object from another user object.
touch()
Update the "touched" timestamp for the user.
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form stripping il...
deleteNewtalk($field, $id)
Clear the new messages flag for the given user.
updateNewtalk($field, $id, $curRev=null)
Add or update the new messages flag.
isBlockedGlobally($ip= '')
Check if user is blocked on all wikis.
blockedBy()
If user is blocked, return the name of the user who placed the block.
string $mQuickTouched
TS_MW timestamp from cache.
$wgReservedUsernames
Array of usernames which may not be registered or logged in from Maintenance scripts can still use th...
static generateRandomPasswordString($minLength=10)
Generate a random string suitable for a password.
static isUsableName($name)
Usernames which fail to pass this function will be blocked from user login and new account registrati...
null for the local wiki Added in
getRealName()
Get the user's real name.
$wgSecureLogin
This is to let user authenticate using https when they come from http.
checkPasswordValidity($password, $purpose= 'login')
Check if this is a valid password for this user.
static findUsersByGroup($groups, $limit=5000, $after=null)
Return the users who are members of the given group(s).
Check if a user's password complies with any password policies that apply to that user...
checkAndSetTouched()
Bump user_touched if it didn't change since this object was loaded.
static newFromId($id)
Static factory method for creation from a given user ID.
changeableGroups()
Returns an array of groups that this user can add and remove.
clearAllNotifications()
Resets all of the given user's page-change notification timestamps.
Represents an invalid password hash.
isLoggedIn()
Get whether the user is logged in.
static getLocalClusterInstance()
Get the main cluster-local cache object.
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency MediaWikiServices
it s the revision text itself In either if gzip is the revision text is gzipped $flags
checkNewtalk($field, $id)
Internal uncached check for new messages.
setPassword($str)
Set the password and reset the random token.
static createNew($name, $params=[])
Add a user to the database, return the user object.
invalidationTokenUrl($token)
Return a URL the user can use to invalidate their email address.
$wgGroupsAddToSelf
A map of group names that the user is in, to group names that those users are allowed to add or revok...
addNewUserLogEntry($action=false, $reason= '')
Add a newuser log entry for this user.
$wgAuth $wgAuth
Authentication plugin.
$wgHiddenPrefs
An array of preferences to not show for the user.
static resetIdByNameCache()
Reset the cache used in idFromName().
setName($str)
Set the user name.
getDBTouched()
Get the user_touched timestamp field (time of last DB updates)
static newFromText($text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
static isIPv6($ip)
Given a string, determine if it as valid IP in IPv6 only.
when a variable name is used in a it is silently declared as a new local masking the global
$wgRevokePermissions
Permission keys revoked from users in each group.
static getPreferences($user, IContextSource $context)
getOptions($flags=0)
Get all user's options.
static newFatal($message)
Factory function for fatal errors.
matchEditToken($val, $salt= '', $request=null, $maxage=null)
Check given value against the token value stored in the session.
setToken($token=false)
Set the random token (used for persistent authentication) Called from loadDefaults() among other plac...
static isIPAddress($ip)
Determine if a string is as valid IP address or network (CIDR prefix).
Multi-datacenter aware caching interface.
$wgUseNPPatrol
Use new page patrolling to check new pages on Special:Newpages.
Value object representing a logged-out user's edit token.
static makeGroupLinkHTML($group, $text= '')
Create a link to the group in HTML, if available; else return the group name.
static makeGroupLinkWiki($group, $text= '')
Create a link to the group in Wikitext, if available; else return the group name. ...
setOption($oname, $val)
Set the given option for a user.
getName()
Get the user name, or the IP of an anonymous user.
see documentation in includes Linker php for Linker::makeImageLink & $time
static selectFields()
Return the list of user fields that should be selected to create a new user object.
string $mName
Cache variables.
string $mRegistration
Cache variables.
$wgEnableEmail
Set to true to enable the e-mail basic features: Password reminders, etc.
setEmailWithConfirmation($str)
Set the user's e-mail address and a confirmation mail if needed.
$wgDnsBlacklistUrls
List of DNS blacklists to use, if $wgEnableDnsBlacklist is true.
int $mEditCount
Cache variables.
wfDebug($text, $dest= 'all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
changeAuthenticationData(array $data)
Changes credentials of the user.
static isEveryoneAllowed($right)
Check if all users may be assumed to have the given permission.
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as $wgLang
The index of the header message $result[1]=The index of the body text message $result[2 through n]=Parameters passed to body text message.Please note the header message cannot receive/use parameters. 'ImportHandleLogItemXMLTag':When parsing a XML tag in a log item.Return false to stop further processing of the tag $reader:XMLReader object $logInfo:Array of information 'ImportHandlePageXMLTag':When parsing a XML tag in a page.Return false to stop further processing of the tag $reader:XMLReader object &$pageInfo:Array of information 'ImportHandleRevisionXMLTag':When parsing a XML tag in a page revision.Return false to stop further processing of the tag $reader:XMLReader object $pageInfo:Array of page information $revisionInfo:Array of revision information 'ImportHandleToplevelXMLTag':When parsing a top level XML tag.Return false to stop further processing of the tag $reader:XMLReader object 'ImportHandleUploadXMLTag':When parsing a XML tag in a file upload.Return false to stop further processing of the tag $reader:XMLReader object $revisionInfo:Array of information 'ImportLogInterwikiLink':Hook to change the interwiki link used in log entries and edit summaries for transwiki imports.&$fullInterwikiPrefix:Interwiki prefix, may contain colons.&$pageTitle:String that contains page title. 'ImportSources':Called when reading from the $wgImportSources configuration variable.Can be used to lazy-load the import sources list.&$importSources:The value of $wgImportSources.Modify as necessary.See the comment in DefaultSettings.php for the detail of how to structure this array. 'InfoAction':When building information to display on the action=info page.$context:IContextSource object &$pageInfo:Array of information 'InitializeArticleMaybeRedirect':MediaWiki check to see if title is a redirect.&$title:Title object for the current page &$request:WebRequest &$ignoreRedirect:boolean to skip redirect check &$target:Title/string of redirect target &$article:Article object 'InternalParseBeforeLinks':during Parser's internalParse method before links but after nowiki/noinclude/includeonly/onlyinclude and other processings.&$parser:Parser object &$text:string containing partially parsed text &$stripState:Parser's internal StripState object 'InternalParseBeforeSanitize':during Parser's internalParse method just before the parser removes unwanted/dangerous HTML tags and after nowiki/noinclude/includeonly/onlyinclude and other processings.Ideal for syntax-extensions after template/parser function execution which respect nowiki and HTML-comments.&$parser:Parser object &$text:string containing partially parsed text &$stripState:Parser's internal StripState object 'InterwikiLoadPrefix':When resolving if a given prefix is an interwiki or not.Return true without providing an interwiki to continue interwiki search.$prefix:interwiki prefix we are looking for.&$iwData:output array describing the interwiki with keys iw_url, iw_local, iw_trans and optionally iw_api and iw_wikiid. 'InvalidateEmailComplete':Called after a user's email has been invalidated successfully.$user:user(object) whose email is being invalidated 'IRCLineURL':When constructing the URL to use in an IRC notification.Callee may modify $url and $query, URL will be constructed as $url.$query &$url:URL to index.php &$query:Query string $rc:RecentChange object that triggered url generation 'IsFileCacheable':Override the result of Article::isFileCacheable()(if true) &$article:article(object) being checked 'IsTrustedProxy':Override the result of IP::isTrustedProxy() &$ip:IP being check &$result:Change this value to override the result of IP::isTrustedProxy() 'IsUploadAllowedFromUrl':Override the result of UploadFromUrl::isAllowedUrl() $url:URL used to upload from &$allowed:Boolean indicating if uploading is allowed for given URL 'isValidEmailAddr':Override the result of Sanitizer::validateEmail(), for instance to return false if the domain name doesn't match your organization.$addr:The e-mail address entered by the user &$result:Set this and return false to override the internal checks 'isValidPassword':Override the result of User::isValidPassword() $password:The password entered by the user &$result:Set this and return false to override the internal checks $user:User the password is being validated for 'Language::getMessagesFileName':$code:The language code or the language we're looking for a messages file for &$file:The messages file path, you can override this to change the location. 'LanguageGetMagic':DEPRECATED!Use $magicWords in a file listed in $wgExtensionMessagesFiles instead.Use this to define synonyms of magic words depending of the language &$magicExtensions:associative array of magic words synonyms $lang:language code(string) 'LanguageGetNamespaces':Provide custom ordering for namespaces or remove namespaces.Do not use this hook to add namespaces.Use CanonicalNamespaces for that.&$namespaces:Array of namespaces indexed by their numbers 'LanguageGetSpecialPageAliases':DEPRECATED!Use $specialPageAliases in a file listed in $wgExtensionMessagesFiles instead.Use to define aliases of special pages names depending of the language &$specialPageAliases:associative array of magic words synonyms $lang:language code(string) 'LanguageGetTranslatedLanguageNames':Provide translated language names.&$names:array of language code=> language name $code:language of the preferred translations 'LanguageLinks':Manipulate a page's language links.This is called in various places to allow extensions to define the effective language links for a page.$title:The page's Title.&$links:Associative array mapping language codes to prefixed links of the form"language:title".&$linkFlags:Associative array mapping prefixed links to arrays of flags.Currently unused, but planned to provide support for marking individual language links in the UI, e.g.for featured articles. 'LanguageSelector':Hook to change the language selector available on a page.$out:The output page.$cssClassName:CSS class name of the language selector. 'LinkBegin':DEPRECATED!Use HtmlPageLinkRendererBegin instead.Used when generating internal and interwiki links in Linker::link(), before processing starts.Return false to skip default processing and return $ret.See documentation for Linker::link() for details on the expected meanings of parameters.$skin:the Skin object $target:the Title that the link is pointing to &$html:the contents that the< a > tag should have(raw HTML) $result
getTitleKey()
Get the user's name escaped by underscores.
static getAllGroups()
Return the set of defined explicit groups.
resetTokenFromOption($oname)
Reset a token stored in the preferences (like the watchlist one).
loadOptions($data=null)
Load the user options either from cache, the database or an array.
static listOptionKinds()
Return a list of the types of user options currently returned by User::getOptionKinds().
$wgGroupPermissions
Permission keys given to users in each group.
getIntOption($oname, $defaultOverride=0)
Get the user's current setting for a given option, as an integer value.
sendMail($subject, $body, $from=null, $replyto=null)
Send an e-mail to this user's account.
static addCallableUpdate($callable, $type=self::POSTSEND)
Add a callable update.
static send($to, $from, $subject, $body, $options=[])
This function will perform a direct (authenticated) login to a SMTP Server to use for mail relaying i...
The User object encapsulates all of the user-specific settings (user_id, name, rights, email address, options, last login time).
string $mEmailTokenExpires
Cache variables.
static getAllRights()
Get a list of all available permissions.
isEmailConfirmed()
Is this user's e-mail address valid-looking and confirmed within limits of the current site configura...
wfTimestamp($outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
getRequest()
Get the WebRequest object.
static purge($wikiId, $userId)
static isValidUserName($name)
Is the input a valid username?
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return true
static edits($uid)
Count the number of edits of a user.
isBlockedFromCreateAccount()
Get whether the user is explicitly blocked from account creation.
do that in ParserLimitReportFormat instead use this to modify the parameters of the image and a DIV can begin in one section and end in another Make sure your code can handle that case gracefully See the EditSectionClearerLink extension for an example zero but section is usually empty its values are the globals values before the output is cached one of or reset my talk my contributions etc etc otherwise the built in rate limiting checks are if enabled $incrBy
setNewpassword($str, $throttle=true)
Set the password for a password reminder or new account email.
timestamp($ts=0)
Convert a timestamp in one of the formats accepted by wfTimestamp() to the format used for inserting ...
static crypt($password, $salt=false)
Make a new-style password hash.
wfDebugLog($logGroup, $text, $dest= 'all', array $context=[])
Send a line to a supplementary debug log file, if configured, or main debug log if not...
loadDefaults($name=false)
Set cached properties to default.
$mOptionsLoaded
Bool Whether the cache variables have been loaded.
getBlock($bFromSlave=true)
Get the block affecting the user, or null if the user is not blocked.
sendConfirmationMail($type= 'created')
Generate a new e-mail confirmation token and send a confirmation/invalidation mail to the user's give...
string $mEmailToken
Cache variables.
design txt This is a brief overview of the new design More thorough and up to date information is available on the documentation wiki at etc Handles the details of getting and saving to the user table of the and dealing with sessions and cookies OutputPage Encapsulates the entire HTML page that will be sent in response to any server request It is used by calling its functions to add in any and then calling but I prefer the flexibility This should also do the output encoding The system allocates a global one in $wgOut Title Represents the title of an article
$wgExtendedLoginCookieExpiration
Default login cookie lifetime, in seconds.
setEmailAuthenticationTimestamp($timestamp)
Set the e-mail authentication timestamp.
static comparePasswords($hash, $password, $userId=false)
Compare a password hash with a plain-text password.
$wgPasswordPolicy
Password policy for local wiki users.
getRegistration()
Get the timestamp of account creation.
wfGetLB($wiki=false)
Get a load balancer object.
$wgRateLimitsExcludedIPs
Array of IPs which should be excluded from rate limits.
wfReadOnly()
Check whether the wiki is in read-only mode.
static getMain()
Static methods.
$wgLegacyEncoding
Set this to eg 'ISO-8859-1' to perform character set conversion when loading old revisions not marked...
setNewtalk($val, $curRev=null)
Update the 'You have new messages!' status.
static groupHasPermission($group, $role)
Check, if the given group has the given permission.
We ve cleaned up the code here by removing clumps of infrequently used code and moving them off somewhere else It s much easier for someone working with this code to see what s _really_ going and make changes or fix bugs In we can take all the code that deals with the little used title reversing we can concentrate it all in an extension file
Base class for the more common types of database errors.
addNewUserLogEntryAutoCreate()
Add an autocreate newuser log entry for this user Used by things like CentralAuth and perhaps other a...
static changeableByGroup($group)
Returns an array of the groups that a particular group can add/remove.
isAllowed($action= '')
Internal mechanics of testing a permission.
isItemLoaded($item, $all= 'all')
Return whether an item has been loaded.
isAnon()
Get whether the user is anonymous.
inDnsBlacklist($ip, $bases)
Whether the given IP is in a given DNS blacklist.
resetOptions($resetKinds=[ 'registered', 'registered-multiselect', 'registered-checkmatrix', 'unused'], IContextSource $context=null)
Reset certain (or all) options to the site defaults.
static newFromTarget($specificTarget, $vagueTarget=null, $fromMaster=false)
Given a target and the target's type, get an existing Block object if possible.
$wgUseFilePatrol
Use file patrolling to check new files on Special:Newfiles.
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content as context as context $options
validateCache($timestamp)
Validate the cache for this account.
static invalidateAllPasswordsForUser($username)
Invalidate all passwords for a user, by name.
Stores a single person's name and email address.
static loadFromTimestamp($db, $title, $timestamp)
Load the revision for the given title with the given timestamp.
$wgImplicitGroups
Implicit groups, aren't shown on Special:Listusers or somewhere else.
static getSaveBlacklist()
doLogout()
Clear the user's session, and reset the instance cache.
integer $queryFlagsUsed
User::READ_* constant bitfield used to load data.
loadFromCache()
Load user data from shared cache, given mId has already been set.
isEmailConfirmationPending()
Check whether there is an outstanding request for e-mail confirmation.
const GAID_FOR_UPDATE
Used to be GAID_FOR_UPDATE define.
incEditCount()
Deferred version of incEditCountImmediate()
newTouchedTimestamp()
Generate a current or new-future timestamp to be stored in the user_touched field when we update thin...
setTarget($target)
Set the target for this block, and update $this->type accordingly.
$wgShowUpdatedMarker
Show "Updated (since my last visit)" marker in RC view, watchlist and history view for watched pages ...
getOptionKinds(IContextSource $context, $options=null)
Return an associative array mapping preferences keys to the kind of a preference they're used for...
$wgProxyList
Big list of banned IP addresses.
static isIPv4($ip)
Given a string, determine if it as valid IP in IPv4 only.
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
static newSystemUser($name, $options=[])
Static factory method for creation of a "system" user from username.
string $mTouched
TS_MW timestamp from the DB.
clearCookie($name, $secure=null, $params=[])
Clear a cookie on the user's client.
canSendEmail()
Is this user allowed to send e-mails within limits of current site configuration? ...
$wgAvailableRights
A list of available rights, in addition to the ones defined by the core.
$wgProxyWhitelist
Proxy whitelist, list of addresses that are assumed to be non-proxy despite what the other methods mi...
string $mEmailAuthenticated
Cache variables.
and(b) You must cause any modified files to carry prominent notices stating that You changed the files
wfDeprecated($function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
static makeTitleSafe($ns, $title, $fragment= '', $interwiki= '')
Create a new Title from a namespace index and a DB key.
static isIP($name)
Does the string match an anonymous IP address?
getBlockedStatus($bFromSlave=true)
Get blocking information.
static getGroupPage($group)
Get the title of a page describing a particular group.
$wgNewPasswordExpiry
The time, in seconds, when an emailed temporary password expires.
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped just before the function returns a value If you return an< a > element with HTML attributes $attribs and contents $html will be returned If you return $ret will be returned after processing after in associative array form externallinks including delete and has completed for all link tables whether this was an auto creation default is conds Array Extra conditions for the No matching items in log is displayed if loglist is empty msgKey Array If you want a nice box with a set this to the key of the message First element is the message additional optional elements are parameters for the key that are processed with wfMessage() -> params() ->parseAsBlock()-offset Set to overwrite offset parameter in $wgRequest set to ''to unsetoffset-wrap String Wrap the message in html(usually something like"<
getPasswordValidity($password)
Given unvalidated password input, return error message on failure.
Allows to change the fields on the form that will be generated are created Can be used to omit specific feeds from being outputted You must not use this hook to add use OutputPage::addFeedLink() instead.&$feedLinks conditions will AND in the final query as a Content object as a Content object $title
requiresHTTPS()
Determine based on the wiki configuration and the user's options, whether this user must be over HTTP...
$wgRateLimits
Simple rate limiter options to brake edit floods.
static $mAllRights
String Cached results of getAllRights()
static run($event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
$wgUseRCPatrol
Use RC Patrolling to check for vandalism (from recent changes and watchlists) New pages and new files...
static getDBOptions($bitfield)
Get an appropriate DB index and options for a query.
design txt This is a brief overview of the new design More thorough and up to date information is available on the documentation wiki at etc Handles the details of getting and saving to the user table of the and dealing with sessions and cookies OutputPage Encapsulates the entire HTML page that will be sent in response to any server request It is used by calling its functions to add text
spreadBlock()
If this (non-anonymous) user is blocked, block the IP address they've successfully logged in from...
static newFromUser(User $user)
Create a new MailAddress object for the given user.
$wgClockSkewFudge
Clock skew or the one-second resolution of time() can occasionally cause cache problems when the user...
$wgAutopromoteOnceLogInRC
Put user rights log entries for autopromotion in recent changes?
$wgEnableUserEmail
Set to true to enable user-to-user e-mail.
wfWikiID()
Get an ASCII string identifying this wiki This is used as a prefix in memcached keys.
$wgNamespacesToBeSearchedDefault
List of namespaces which are searched by default.
presenting them properly to the user as errors is done by the caller return true use this to change the list i e etc $rev
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses & $ret
getTokenUrl($page, $token)
Internal function to format the e-mail validation/invalidation URLs.
setInternalPassword($str)
Set the password and reset the random token unconditionally.
$wgDisableAnonTalk
Disable links to talk pages of anonymous users (IPs) in listings on special pages like page history...
static getCacheSetOptions(IDatabase $db1)
Merge the result of getSessionLagStatus() for several DBs using the most pessimistic values to estima...
namespace and then decline to actually register it & $namespaces
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output modifiable & $code
loadFromDatabase($flags=self::READ_LATEST)
Load user and user_group data from the database.
string $mToken
Cache variables.
isWatched($title, $checkRights=self::CHECK_USER_RIGHTS)
Check the watched status of an article.
static newInvalidPassword()
Create an InvalidPassword.
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a local account $user
static link($target, $html=null, $customAttribs=[], $query=[], $options=[])
This function returns an HTML link to the given target.
static normalizeKey($key)
Normalize a skin preference value to a form that can be loaded.
useRCPatrol()
Check whether to enable recent changes patrol features for this user.
$wgPasswordSender
Sender email address for e-mail notifications.
isBlocked($bFromSlave=true)
Check if user is blocked.
getOption($oname, $defaultOverride=null, $ignoreHidden=false)
Get the user's current setting for a given option.
makeUpdateConditions(DatabaseBase $db, array $conditions)
Builds update conditions.
static getGroupName($group)
Get the localized descriptive name for a group, if it exists.
$wgEmailAuthentication
Require email authentication before sending mail to an email address.
$mNewtalk
Lazy-initialized variables, invalidated with clearInstanceCache.
invalidateEmail()
Invalidate the user's e-mail confirmation, and unauthenticate the e-mail address if it was already co...
loadGroups()
Load the groups from the database if they aren't already loaded.
saveOptions()
Saves the non-default options for this user, as previously set e.g.
idForName($flags=0)
If only this user's username is known, and it exists, return the user ID.
$wgCookieExpiration
Default cookie lifetime, in seconds.
const TS_MW
MediaWiki concatenated string timestamp (YYYYMMDDHHMMSS)
static passwordChangeInputAttribs()
Provide an array of HTML5 attributes to put on an input element intended for the user to enter a new ...
Database abstraction object.
static newFromId($id, $flags=0)
Load a page revision from a given revision ID number.
$wgApplyIpBlocksToXff
Whether to look at the X-Forwarded-For header's list of (potentially spoofed) IPs and apply IP blocks...
setId($v)
Set the user and reload all fields according to a given ID.
getStubThreshold()
Get the user preferred stub threshold.
getRequest()
Get the WebRequest object to use with this object.
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
string $mEmail
Cache variables.
setExtendedLoginCookie($name, $value, $secure)
Set an extended login cookie on the user's client.
static getBlocksForIPList(array $ipChain, $isAnon, $fromMaster=false)
Get all blocks that match any IP from an array of IP addresses.
this hook is for auditing only $req
getNewtalk()
Check if the user has new messages.
this hook is for auditing only or null if authentication failed before getting that far $username
static newFromConfirmationCode($code, $flags=0)
Factory method to fetch whichever user has a given email confirmation code.
loadFromRow($row, $data=null)
Initialize this object from a row from the user table.
getGroups()
Get the list of explicit group memberships this user has.
__construct()
Lightweight constructor for an anonymous user.
static getGroupMember($group, $username= '#')
Get the localized descriptive name for a member of a group, if it exists.
array $mGroups
Cache variables.
confirmationTokenUrl($token)
Return a URL the user can use to confirm their email address.
Class for creating log entries manually, to inject them into the database.
error also a ContextSource you ll probably need to make sure the header is varied on $request
removeGroup($group)
Remove the user from the given group.
prevents($action, $x=null)
Get/set whether the Block prevents a given action.
static hasFlags($bitfield, $flags)
The ContentHandler facility adds support for arbitrary content types on wiki pages
$wgMinimalPasswordLength
Specifies the minimal length of a user password.
spreadAnyEditBlock()
If this user is logged-in and blocked, block any IP address they've successfully logged in from...
useFilePatrol()
Check whether to enable new files patrol features for this user.
static hmac($data, $key, $raw=true)
Generate an acceptably unstable one-way-hmac of some text making use of the best hash algorithm that ...
getEffectiveGroups($recache=false)
Get the list of implicit group memberships this user has.
getId()
Get the user's ID.
getEmailAuthenticationTimestamp()
Get the timestamp of the user's e-mail authentication.
Show an error when any operation involving passwords fails to run.
addToDatabase()
Add this existing user object to the database.
$wgInvalidUsernameCharacters
Characters to prevent during new account creations.
invalidateCache()
Immediately touch the user data cache for this account.
getTokenFromOption($oname)
Get a token stored in the preferences (like the watchlist one), resetting it if it's empty (and savin...
removeWatch($title, $checkRights=self::CHECK_USER_RIGHTS)
Stop watching an article.
$wgDefaultSkin
Default skin, for new users and anonymous visitors.
confirmEmail()
Mark the e-mail address confirmed.
getGlobalBlock($ip= '')
Check if user is blocked on all wikis.
static generateHex($chars, $forceStrong=false)
Generate a run of (ideally) cryptographically random data and return it in hexadecimal string format...
setEmail($str)
Set the user's e-mail address.
initEditCount($add=0)
Initialize user_editcount from data out of the revision table.
$wgDisableAuthManager
Disable AuthManager.
static getPasswordFactory()
Lazily instantiate and return a factory object for making passwords.
static isCreatableName($name)
Usernames which fail to pass this function will be blocked from new account registrations, but may be used internally either by batch processes or by user accounts which have already been created.
static newFromSession(WebRequest $request=null)
Create a new user object using data from session.
getEditCount()
Get the user's edit count.
getUserPage()
Get this user's personal page title.
getInstanceForUpdate()
Get a new instance of this user that was loaded from the master via a locking read.
static idFromName($name, $flags=self::READ_NORMAL)
Get database id given a user name.
$wgPasswordSalt
For compatibility with old installations set to false.
useNPPatrol()
Check whether to enable new pages patrol features for this user.
$wgAddGroups
$wgAddGroups and $wgRemoveGroups can be used to give finer control over who can assign which groups a...
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set and then return false from the hook function Ensure you consume the ChangeTagAfterDelete hook to carry out custom deletion actions as context called by AbstractContent::getParserOutput May be used to override the normal model specific rendering of page content as context as context the output can only depend on parameters provided to this hook not on global state indicating whether full HTML should be generated If generation of HTML may be but other information should still be present in the ParserOutput object to manipulate or replace but no entry for that model exists in $wgContentHandlers if desired whether it is OK to use $contentModel on $title Handler functions that modify $ok should generally return false to prevent further hooks from further modifying $ok inclusive $limit
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as and the local content language as $wgContLang
Interface for database access objects.
setCookies($request=null, $secure=null, $rememberMe=false)
Persist this user's session (e.g.
getDatePreference()
Get the user's preferred date format.
getBlockId()
If user is blocked, return the ID for the block.
getNewMessageRevisionId()
Get the revision ID for the last talk page revision viewed by the talk page owner.
$mFrom
String Initialization data source if mLoadedItems!==true.
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist e g Watchlist removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set $status
static consume(ScopedCallback &$sc=null)
Trigger a scoped callback and destroy it.
getEditToken($salt= '', $request=null)
Initialize (if necessary) and return a session token value which can be used in edit forms to show th...
static newFatalPermissionDeniedStatus($permission)
Factory function for fatal permission-denied errors.
getEditTokenObject($salt= '', $request=null)
Initialize (if necessary) and return a session token value which can be used in edit forms to show th...
isLocked()
Check if user account is locked.
wfMemcKey()
Make a cache key for the local wiki.
static validateEmail($addr)
Does a string look like an e-mail address?
canReceiveEmail()
Is this user allowed to receive e-mails within limits of current site configuration?
Some quick notes on the file repository architecture Functionality as driven by data model *The repository object stores configuration information about a file storage method *The file object is a process local cache of information about a particular file Thus the file object is the primary public entry point for obtaining information about since access via the file object can be cached
equals(User $user)
Checks if two user objects point to the same user.
$wgBlockAllowsUTEdit
Set this to true to allow blocked users to edit their own user talk page.
loadFromId($flags=self::READ_NORMAL)
Load user table data, given mId has already been set.
const TS_UNIX
Unix time - the number of seconds since 1970-01-01 00:00:00 UTC.
setRealName($str)
Set the user's real name.
addWatch($title, $checkRights=self::CHECK_USER_RIGHTS)
Watch an article.
array $mOptionOverrides
Cache variables.
checkTemporaryPassword($plaintext)
Check if the given clear-text password matches the temporary password sent by e-mail for password res...
static logException($e)
Log an exception to the exception log (if enabled).
static getDefaultOptions()
Combine the language default options with any site-specific options and add the default language vari...
const INVALID_TOKEN
string An invalid value for user_token
setItemLoaded($item)
Set that an item has been loaded.
wfTimestampOrNull($outputtype=TS_UNIX, $ts=null)
Return a formatted timestamp, or null if input is null.
static getDefaultOption($opt)
Get a given default option value.
string $mRealName
Cache variables.
isSafeToLoad()
Test if it's safe to load this User object.
static getSubnet($ip)
Returns the subnet of a given IP.
getCacheKey(WANObjectCache $cache)
static getGroupPermissions($groups)
Get the permissions associated with a given list of groups.
static array $languagesWithVariants
languages supporting variants
getTalkPage()
Get this user's talk page title.
$wgPasswordReminderResendTime
Minimum time, in hours, which must elapse between password reminder emails for a given account...
getToken($forceCreation=true)
Get the user's current token.
const EDIT_TOKEN_SUFFIX
Global constant made accessible as class constants so that autoloader magic can be used...
isPingLimitable()
Is this user subject to rate limiting?
static getRightDescription($right)
Get the description of a given right.
do that in ParserLimitReportFormat instead use this to modify the parameters of the image and a DIV can begin in one section and end in another Make sure your code can handle that case gracefully See the EditSectionClearerLink extension for an example zero but section is usually empty its values are the globals values before the output is cached one of or reset my talk page
if(is_null($wgLocalTZoffset)) if(!$wgDBerrorLogTZ) $wgRequest
do that in ParserLimitReportFormat instead use this to modify the parameters of the image and a DIV can begin in one section and end in another Make sure your code can handle that case gracefully See the EditSectionClearerLink extension for an example zero but section is usually empty its values are the globals values before the output is cached one of or reset my talk my contributions etc etc otherwise the built in rate limiting checks are if enabled allows for interception of redirect as a string mapping parameter names to values & $type
static makeTitle($ns, $title, $fragment= '', $interwiki= '')
Create a new Title from a namespace index and a DB key.
static $mCacheVars
Array of Strings List of member variables which are saved to the shared cache (memcached).
static getGroupsWithPermission($role)
Get all the groups who have a given permission.
static newGood($value=null)
Factory function for good results.
getRights()
Get the permissions this user has.
getFormerGroups()
Returns the groups the user has belonged to.
blockedFor()
If user is blocked, return the specified reason for the block.
do that in ParserLimitReportFormat instead use this to modify the parameters of the image and a DIV can begin in one section and end in another Make sure your code can handle that case gracefully See the EditSectionClearerLink extension for an example zero but section is usually empty its values are the globals values before the output is cached $page
$wgEnableDnsBlacklist
Whether to use DNS blacklists in $wgDnsBlacklistUrls to check for open proxies.
setPasswordInternal($str)
Actually set the password and such.
incEditCountImmediate()
Increment the user's edit-count field.
addGroup($group)
Add the user to the given group.
confirmationToken(&$expiration)
Generate, store, and return a new e-mail confirmation code.
getTouched()
Get the user touched timestamp.
$mLoadedItems
Array with already loaded items or true if all items have been loaded.
Allows to change the fields on the form that will be generated $name