Block::prevents is used in several different ways:
- It is used to calculate whether a block prevents the user from executing certain rights. It does this with a mixture of hard-coding, getting the properties of a Block, and possibly overriding based on global configs. It is also used to calculate whether a block prevents the user from editing their own talk page, using 'editownusertalk', which does not appear in any list of rights, but is a string passed into Block::prevents when needed
- It is used to set Boolean block properties corresponding to ipb_create_account, ipb_block_email and ipb_allow_usertalk. Confusingly, it does not always return the same value that it set, because of (1)
- It is used to get the above listed properties; however, because of (1), it does not always get the actual property. One example of where this could be a problem is in SpecialBlock::processForm, when updating an existing block. Flags set by default on the new block can be different from the old block due to how global configs interact with the old block's flags, even though the user performing the block didn't intentionally change them. This will be a problem if the global configs are ever altered after the block is updated.
Block::prevents could be split out into:
- get/setters for the Boolean flags
- a method for determining whether the user is blocked from their own user talk page
- a method for determining whether a right is blocked, which would do most of what Block::prevents currently does, except for the above points
Once we separate these methods, then in contexts where we are really interested in the properties set on the block, we can use the get/setters, and know that the return value reflects the database.