MediaWiki  master
Autopromote.php
Go to the documentation of this file.
1 <?php
25 use Wikimedia\IPUtils;
26 
31 class Autopromote {
38  public static function getAutopromoteGroups( User $user ) {
39  global $wgAutopromote;
40 
41  $promote = [];
42 
43  foreach ( $wgAutopromote as $group => $cond ) {
44  if ( self::recCheckCondition( $cond, $user ) ) {
45  $promote[] = $group;
46  }
47  }
48 
49  Hooks::runner()->onGetAutoPromoteGroups( $user, $promote );
50 
51  return $promote;
52  }
53 
66  public static function getAutopromoteOnceGroups( User $user, $event ) {
67  global $wgAutopromoteOnce;
68 
69  $promote = [];
70 
71  if ( isset( $wgAutopromoteOnce[$event] ) && count( $wgAutopromoteOnce[$event] ) ) {
72  $currentGroups = $user->getGroups();
73  $formerGroups = $user->getFormerGroups();
74  foreach ( $wgAutopromoteOnce[$event] as $group => $cond ) {
75  // Do not check if the user's already a member
76  if ( in_array( $group, $currentGroups ) ) {
77  continue;
78  }
79  // Do not autopromote if the user has belonged to the group
80  if ( in_array( $group, $formerGroups ) ) {
81  continue;
82  }
83  // Finally - check the conditions
84  if ( self::recCheckCondition( $cond, $user ) ) {
85  $promote[] = $group;
86  }
87  }
88  }
89 
90  return $promote;
91  }
92 
109  private static function recCheckCondition( $cond, User $user ) {
110  $validOps = [ '&', '|', '^', '!' ];
111 
112  if ( is_array( $cond ) && count( $cond ) >= 2 && in_array( $cond[0], $validOps ) ) {
113  # Recursive condition
114  if ( $cond[0] == '&' ) { // AND (all conds pass)
115  foreach ( array_slice( $cond, 1 ) as $subcond ) {
116  if ( !self::recCheckCondition( $subcond, $user ) ) {
117  return false;
118  }
119  }
120 
121  return true;
122  } elseif ( $cond[0] == '|' ) { // OR (at least one cond passes)
123  foreach ( array_slice( $cond, 1 ) as $subcond ) {
124  if ( self::recCheckCondition( $subcond, $user ) ) {
125  return true;
126  }
127  }
128 
129  return false;
130  } elseif ( $cond[0] == '^' ) { // XOR (exactly one cond passes)
131  if ( count( $cond ) > 3 ) {
132  wfWarn( 'recCheckCondition() given XOR ("^") condition on three or more conditions.' .
133  ' Check your $wgAutopromote and $wgAutopromoteOnce settings.' );
134  }
135  return self::recCheckCondition( $cond[1], $user )
136  xor self::recCheckCondition( $cond[2], $user );
137  } elseif ( $cond[0] == '!' ) { // NOT (no conds pass)
138  foreach ( array_slice( $cond, 1 ) as $subcond ) {
139  if ( self::recCheckCondition( $subcond, $user ) ) {
140  return false;
141  }
142  }
143 
144  return true;
145  }
146  }
147  // If we got here, the array presumably does not contain other conditions;
148  // it's not recursive. Pass it off to self::checkCondition.
149  if ( !is_array( $cond ) ) {
150  $cond = [ $cond ];
151  }
152 
153  return self::checkCondition( $cond, $user );
154  }
155 
166  private static function checkCondition( $cond, User $user ) {
167  global $wgEmailAuthentication;
168  if ( count( $cond ) < 1 ) {
169  return false;
170  }
171 
172  switch ( $cond[0] ) {
174  if ( Sanitizer::validateEmail( $user->getEmail() ) ) {
175  if ( $wgEmailAuthentication ) {
176  return (bool)$user->getEmailAuthenticationTimestamp();
177  } else {
178  return true;
179  }
180  }
181  return false;
182  case APCOND_EDITCOUNT:
183  $reqEditCount = $cond[1];
184 
185  // T157718: Avoid edit count lookup if specified edit count is 0 or invalid
186  if ( $reqEditCount <= 0 ) {
187  return true;
188  }
189  return $user->getEditCount() >= $reqEditCount;
190  case APCOND_AGE:
191  $age = time() - (int)wfTimestampOrNull( TS_UNIX, $user->getRegistration() );
192  return $age >= $cond[1];
194  $age = time() - (int)wfTimestampOrNull( TS_UNIX, $user->getFirstEditTimestamp() );
195  return $age >= $cond[1];
196  case APCOND_INGROUPS:
197  $groups = array_slice( $cond, 1 );
198  return count( array_intersect( $groups, $user->getGroups() ) ) == count( $groups );
199  case APCOND_ISIP:
200  return $cond[1] == $user->getRequest()->getIP();
201  case APCOND_IPINRANGE:
202  return IPUtils::isInRange( $user->getRequest()->getIP(), $cond[1] );
203  case APCOND_BLOCKED:
204  return $user->getBlock() && $user->getBlock()->isSitewide();
205  case APCOND_ISBOT:
206  return in_array( 'bot', MediaWikiServices::getInstance()
208  ->getGroupPermissions( $user->getGroups() ) );
209  default:
210  $result = null;
211  Hooks::runner()->onAutopromoteCondition( $cond[0],
212  array_slice( $cond, 1 ), $user, $result );
213  if ( $result === null ) {
214  throw new MWException( "Unrecognized condition {$cond[0]} for autopromotion!" );
215  }
216 
217  return (bool)$result;
218  }
219  }
220 }
APCOND_ISBOT
const APCOND_ISBOT
Definition: Defines.php:202
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:149
User\getEditCount
getEditCount()
Get the user's edit count.
Definition: User.php:3065
Autopromote\recCheckCondition
static recCheckCondition( $cond, User $user)
Recursively check a condition.
Definition: Autopromote.php:109
$wgEmailAuthentication
$wgEmailAuthentication
Require email authentication before sending mail to an email address.
Definition: DefaultSettings.php:1882
Autopromote\getAutopromoteGroups
static getAutopromoteGroups(User $user)
Get the groups for the given user based on $wgAutopromote.
Definition: Autopromote.php:38
APCOND_EDITCOUNT
const APCOND_EDITCOUNT
Definition: Defines.php:194
Sanitizer\validateEmail
static validateEmail( $addr)
Does a string look like an e-mail address?
Definition: Sanitizer.php:1980
APCOND_AGE
const APCOND_AGE
Definition: Defines.php:195
User\getGroups
getGroups()
Get the list of explicit group memberships this user has.
Definition: User.php:2991
User\getEmailAuthenticationTimestamp
getEmailAuthenticationTimestamp()
Get the timestamp of the user's e-mail authentication.
Definition: User.php:2609
User\getRequest
getRequest()
Get the WebRequest object to use with this object.
Definition: User.php:3255
User\getEmail
getEmail()
Get the user's e-mail address.
Definition: User.php:2599
$wgAutopromote
$wgAutopromote
Array containing the conditions of automatic promotion of a user to specific groups.
Definition: DefaultSettings.php:5820
MWException
MediaWiki exception.
Definition: MWException.php:26
Autopromote\checkCondition
static checkCondition( $cond, User $user)
As recCheckCondition, but not recursive.
Definition: Autopromote.php:166
APCOND_AGE_FROM_EDIT
const APCOND_AGE_FROM_EDIT
Definition: Defines.php:200
getPermissionManager
getPermissionManager()
APCOND_ISIP
const APCOND_ISIP
Definition: Defines.php:198
wfTimestampOrNull
wfTimestampOrNull( $outputtype=TS_UNIX, $ts=null)
Return a formatted timestamp, or null if input is null.
Definition: GlobalFunctions.php:1822
APCOND_BLOCKED
const APCOND_BLOCKED
Definition: Defines.php:201
User\getBlock
getBlock( $fromReplica=true)
Get the block affecting the user, or null if the user is not blocked.
Definition: User.php:1949
User\getFirstEditTimestamp
getFirstEditTimestamp()
Get the timestamp of the first edit.
Definition: User.php:4253
User\getFormerGroups
getFormerGroups()
Returns the groups the user has belonged to.
Definition: User.php:3055
Hooks\runner
static runner()
Get a HookRunner instance for calling hooks using the new interfaces.
Definition: Hooks.php:171
Autopromote
This class checks if user can get extra rights because of conditions specified in $wgAutopromote.
Definition: Autopromote.php:31
APCOND_INGROUPS
const APCOND_INGROUPS
Definition: Defines.php:197
Autopromote\getAutopromoteOnceGroups
static getAutopromoteOnceGroups(User $user, $event)
Get the groups for the given user based on the given criteria.
Definition: Autopromote.php:66
User\getRegistration
getRegistration()
Get the timestamp of account creation.
Definition: User.php:4239
wfWarn
wfWarn( $msg, $callerOffset=1, $level=E_USER_NOTICE)
Send a warning either to the debug log or in a PHP error depending on $wgDevelopmentWarnings.
Definition: GlobalFunctions.php:1051
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:55
$wgAutopromoteOnce
$wgAutopromoteOnce
Automatically add a usergroup to any user who matches certain conditions.
Definition: DefaultSettings.php:5845
APCOND_EMAILCONFIRMED
const APCOND_EMAILCONFIRMED
Definition: Defines.php:196
APCOND_IPINRANGE
const APCOND_IPINRANGE
Definition: Defines.php:199