Adding some notes in case it's helpful. I set local config:
$wgAutoConfirmCount = 25; $wgAutopromote = [ 'autoconfirmed' => [ '&', [ APCOND_EDITCOUNT, &$wgAutoConfirmCount ], [ '!', [ APCOND_BLOCKED ] ], ], ];
And checked that a partially blocked user with 25 edits had "Implicit member of: Autoconfirmed users" on Special:Userrights.
I looked through the code to try to find everything that depends (directly or indirectly) on the Autopromote class.
Checked 'autoconfirmed' is or is not included in the user's list of groups depending on whether the user is sitewide blocked (including IP blocks if logged in as the same user) for:
- The JS variable: mediaWiki.config.values.wgUserGroups
Checked the user has certain rights depending on whether they are sitewide blocked (this time including composite blocks):
- Editing protected pages (editsemiprotected)
- File upload and reupload (via UI and API)
- Creating account (if 'createaccount' was allowed only for autoconfirmed group)
- Patrol (if 'patrol' right added to autoconfirmed group)
- Delete (if 'delete' right added to autoconfirmed group)
And a few others:
- Custom $wgPasswordPolicy for the autoconfirmed group (curiously, this does not take IP blocks into account)
- User preferences (api.php?action=options)
- Group specific site JS
I also varied the user's interface language, in case this caused any issues.
For $wgAutopromoteOnce, config.
$wgAutopromoteOnce = [ 'onEdit' => [ 'patroller' => [ '&', [ APCOND_EDITCOUNT, &$wgAutoConfirmCount ], [ '!', [ APCOND_BLOCKED ] ], ], ], 'onView' => [ 'rollbacker' => [ '&', [ APCOND_EDITCOUNT, &$wgAutoConfirmCount ], [ '!', [ APCOND_BLOCKED ] ], ], ], ];
Checked the user had the groups 'patroller' and 'rollbacker' added (permanently) for actions including:
- rollback (including via api)
Multi-Content Revisions also supposedly trigger autopromotions, but I could not figure out how to use them (or even if they are being used anywhere).
Looking at the code, we had previously been calling $user->getBlock(). Now we are also calling $user->getBlock()->isSitewide(). Assuming isSitewide() always returns a boolean, there is no reason to think that the latter will cause problems where the former did not.