* @return Bool
*/
public static function isIP( $name ) {
- return preg_match('/^\d{1,3}\.\d{1,3}\.\d{1,3}\.(?:xxx|\d{1,3})$/',$name) || IP::isIPv6($name);
+ return preg_match( '/^\d{1,3}\.\d{1,3}\.\d{1,3}\.(?:xxx|\d{1,3})$/', $name ) || IP::isIPv6( $name );
}
/**
public function pingLimiter( $action = 'edit' ) {
# Call the 'PingLimiter' hook
$result = false;
- if( !wfRunHooks( 'PingLimiter', array( &$this, $action, $result ) ) ) {
+ if( !wfRunHooks( 'PingLimiter', array( &$this, $action, &$result ) ) ) {
return $result;
}
* @param $bFromSlave Bool Whether to check the slave database instead of the master
* @return Block|null
*/
- public function getBlock( $bFromSlave = true ){
+ public function getBlock( $bFromSlave = true ) {
$this->getBlockedStatus( $bFromSlave );
return $this->mBlock instanceof Block ? $this->mBlock : null;
}
# set it, and then it was disabled removing their ability to change it). But
# we don't want to erase the preferences in the database in case the preference
# is re-enabled again. So don't touch $mOptions, just override the returned value
- if( in_array( $oname, $wgHiddenPrefs ) && !$ignoreHidden ){
+ if( in_array( $oname, $wgHiddenPrefs ) && !$ignoreHidden ) {
return self::getDefaultOption( $oname );
}
# set it, and then it was disabled removing their ability to change it). But
# we don't want to erase the preferences in the database in case the preference
# is re-enabled again. So don't touch $mOptions, just override the returned value
- foreach( $wgHiddenPrefs as $pref ){
+ foreach( $wgHiddenPrefs as $pref ) {
$default = self::getDefaultOption( $pref );
- if( $default !== null ){
+ if( $default !== null ) {
$options[$pref] = $default;
}
}
}
/**
- * Reset all options to the site defaults
+ * Return a list of the types of user options currently returned by
+ * User::getOptionKinds().
+ *
+ * Currently, the option kinds are:
+ * - 'registered' - preferences which are registered in core MediaWiki or
+ * by extensions using the UserGetDefaultOptions hook.
+ * - 'registered-multiselect' - as above, using the 'multiselect' type.
+ * - 'userjs' - preferences with names starting with 'userjs-', intended to
+ * be used by user scripts.
+ * - 'unused' - preferences about which MediaWiki doesn't know anything.
+ * These are usually legacy options, removed in newer versions.
+ *
+ * The API (and possibly others) use this function to determine the possible
+ * option types for validation purposes, so make sure to update this when a
+ * new option kind is added.
+ *
+ * @see User::getOptionKinds
+ * @return array Option kinds
+ */
+ public static function listOptionKinds() {
+ return array(
+ 'registered',
+ 'registered-multiselect',
+ 'userjs',
+ 'unused'
+ );
+ }
+
+ /**
+ * Return an associative array mapping preferences keys to the kind of a preference they're
+ * used for. Different kinds are handled differently when setting or reading preferences.
+ *
+ * See User::listOptionKinds for the list of valid option types that can be provided.
+ *
+ * @see User::listOptionKinds
+ * @param $context IContextSource
+ * @param $options array assoc. array with options keys to check as keys. Defaults to $this->mOptions.
+ * @return array the key => kind mapping data
+ */
+ public function getOptionKinds( IContextSource $context, $options = null ) {
+ $this->loadOptions();
+ if ( $options === null ) {
+ $options = $this->mOptions;
+ }
+
+ $prefs = Preferences::getPreferences( $this, $context );
+ $mapping = array();
+
+ // Multiselect options are stored in the database with one key per
+ // option, each having a boolean value. Extract those keys.
+ $multiselectOptions = array();
+ foreach ( $prefs as $name => $info ) {
+ if ( ( isset( $info['type'] ) && $info['type'] == 'multiselect' ) ||
+ ( isset( $info['class'] ) && $info['class'] == 'HTMLMultiSelectField' ) ) {
+ $opts = HTMLFormField::flattenOptions( $info['options'] );
+ $prefix = isset( $info['prefix'] ) ? $info['prefix'] : $name;
+
+ foreach ( $opts as $value ) {
+ $multiselectOptions["$prefix$value"] = true;
+ }
+
+ unset( $prefs[$name] );
+ }
+ }
+
+ // $value is ignored
+ foreach ( $options as $key => $value ) {
+ if ( isset( $prefs[$key] ) ) {
+ $mapping[$key] = 'registered';
+ } elseif( isset( $multiselectOptions[$key] ) ) {
+ $mapping[$key] = 'registered-multiselect';
+ } elseif ( substr( $key, 0, 7 ) === 'userjs-' ) {
+ $mapping[$key] = 'userjs';
+ } else {
+ $mapping[$key] = 'unused';
+ }
+ }
+
+ return $mapping;
+ }
+
+ /**
+ * Reset certain (or all) options to the site defaults
+ *
+ * The optional parameter determines which kinds of preferences will be reset.
+ * Supported values are everything that can be reported by getOptionKinds()
+ * and 'all', which forces a reset of *all* preferences and overrides everything else.
+ *
+ * @param $resetKinds array|string which kinds of preferences to reset. Defaults to
+ * array( 'registered', 'registered-multiselect', 'unused' )
+ * for backwards-compatibility.
+ * @param $context IContextSource|null context source used when $resetKinds
+ * does not contain 'all', passed to getOptionKinds().
+ * Defaults to RequestContext::getMain() when null.
*/
- public function resetOptions() {
+ public function resetOptions(
+ $resetKinds = array( 'registered', 'registered-multiselect', 'unused' ),
+ IContextSource $context = null
+ ) {
$this->load();
+ $defaultOptions = self::getDefaultOptions();
- $this->mOptions = self::getDefaultOptions();
+ if ( !is_array( $resetKinds ) ) {
+ $resetKinds = array( $resetKinds );
+ }
+
+ if ( in_array( 'all', $resetKinds ) ) {
+ $newOptions = $defaultOptions;
+ } else {
+ if ( $context === null ) {
+ $context = RequestContext::getMain();
+ }
+
+ $optionKinds = $this->getOptionKinds( $context );
+ $resetKinds = array_intersect( $resetKinds, self::listOptionKinds() );
+ $newOptions = array();
+
+ // Use default values for the options that should be deleted, and
+ // copy old values for the ones that shouldn't.
+ foreach ( $this->mOptions as $key => $value ) {
+ if ( in_array( $optionKinds[$key], $resetKinds ) ) {
+ if ( array_key_exists( $key, $defaultOptions ) ) {
+ $newOptions[$key] = $defaultOptions[$key];
+ }
+ } else {
+ $newOptions[$key] = $value;
+ }
+ }
+ }
+
+ $this->mOptions = $newOptions;
$this->mOptionsLoaded = true;
}
*/
public function isAllowedAny( /*...*/ ) {
$permissions = func_get_args();
- foreach( $permissions as $permission ){
- if( $this->isAllowed( $permission ) ){
+ foreach( $permissions as $permission ) {
+ if( $this->isAllowed( $permission ) ) {
return true;
}
}
*/
public function isAllowedAll( /*...*/ ) {
$permissions = func_get_args();
- foreach( $permissions as $permission ){
- if( !$this->isAllowed( $permission ) ){
+ foreach( $permissions as $permission ) {
+ if( !$this->isAllowed( $permission ) ) {
return false;
}
}
return;
}
$id = $this->getId();
- if( $id != 0 ) {
+ if( $id != 0 ) {
$dbw = wfGetDB( DB_MASTER );
$dbw->update( 'watchlist',
array( /* SET */
wfDeprecated( __METHOD__, '1.17' );
global $wgUseDynamicDates, $wgRenderHashAppend, $wgLang, $wgContLang;
- if( $this->mHash ){
+ if( $this->mHash ) {
return $this->mHash;
}
*/
public function isBlockedFromCreateAccount() {
$this->getBlockedStatus();
- if( $this->mBlock && $this->mBlock->prevents( 'createaccount' ) ){
+ if( $this->mBlock && $this->mBlock->prevents( 'createaccount' ) ) {
return $this->mBlock;
}
# bug 13611: if the IP address the user is trying to create an account from is
# blocked with createaccount disabled, prevent new account creation there even
# when the user is logged in
- if( $this->mBlockedFromCreateAccount === false ){
+ if ( $this->mBlockedFromCreateAccount === false && !$this->isAllowed( 'ipblock-exempt' ) ) {
$this->mBlockedFromCreateAccount = Block::newFromTarget( null, $this->getRequest()->getIP() );
}
return $this->mBlockedFromCreateAccount instanceof Block && $this->mBlockedFromCreateAccount->prevents( 'createaccount' )
}
/**
- * Add a newuser log entry for this user. Before 1.19 the return value was always true.
+ * Add a newuser log entry for this user.
+ * Before 1.19 the return value was always true.
+ *
+ * @param $action string|bool: account creation type.
+ * - String, one of the following values:
+ * - 'create' for an anonymous user creating an account for himself.
+ * This will force the action's performer to be the created user itself,
+ * no matter the value of $wgUser
+ * - 'create2' for a logged in user creating an account for someone else
+ * - 'byemail' when the created user will receive its password by e-mail
+ * - Boolean means whether the account was created by e-mail (deprecated):
+ * - true will be converted to 'byemail'
+ * - false will be converted to 'create' if this object is the same as
+ * $wgUser and to 'create2' otherwise
*
- * @param $byEmail Boolean: account made by email?
* @param $reason String: user supplied reason
*
* @return int|bool True if not $wgNewUserLog; otherwise ID of log item or 0 on failure
*/
- public function addNewUserLogEntry( $byEmail = false, $reason = '' ) {
- global $wgUser, $wgContLang, $wgNewUserLog;
+ public function addNewUserLogEntry( $action = false, $reason = '' ) {
+ global $wgUser, $wgNewUserLog;
if( empty( $wgNewUserLog ) ) {
return true; // disabled
}
- if( $this->getName() == $wgUser->getName() ) {
- $action = 'create';
- } else {
- $action = 'create2';
- if ( $byEmail ) {
- if ( $reason === '' ) {
- $reason = wfMessage( 'newuserlog-byemail' )->inContentLanguage()->text();
- } else {
- $reason = $wgContLang->commaList( array(
- $reason, wfMessage( 'newuserlog-byemail' )->inContentLanguage()->text() ) );
- }
+ if ( $action === true ) {
+ $action = 'byemail';
+ } elseif ( $action === false ) {
+ if ( $this->getName() == $wgUser->getName() ) {
+ $action = 'create';
+ } else {
+ $action = 'create2';
}
}
- $log = new LogPage( 'newusers' );
- return (int)$log->addEntry(
- $action,
- $this->getUserPage(),
- $reason,
- array( $this->getId() )
- );
+
+ if ( $action === 'create' || $action === 'autocreate' ) {
+ $performer = $this;
+ } else {
+ $performer = $wgUser;
+ }
+
+ $logEntry = new ManualLogEntry( 'newusers', $action );
+ $logEntry->setPerformer( $performer );
+ $logEntry->setTarget( $this->getUserPage() );
+ $logEntry->setComment( $reason );
+ $logEntry->setParameters( array(
+ '4::userid' => $this->getId(),
+ ) );
+ $logid = $logEntry->insert();
+
+ if ( $action !== 'autocreate' ) {
+ $logEntry->publish( $logid );
+ }
+
+ return (int)$logid;
}
/**
* Add an autocreate newuser log entry for this user
* Used by things like CentralAuth and perhaps other authplugins.
+ * Consider calling addNewUserLogEntry() directly instead.
*
* @return bool
*/
public function addNewUserLogEntryAutoCreate() {
- global $wgNewUserLog;
- if( !$wgNewUserLog ) {
- return true; // disabled
- }
- $log = new LogPage( 'newusers', false );
- $log->addEntry( 'autocreate', $this->getUserPage(), '', array( $this->getId() ), $this );
+ $this->addNewUserLogEntry( 'autocreate' );
+
return true;
}