**Problem**
The [[ https://www.mediawiki.org/wiki/Manual:Hooks/GetBlockedStatus | GetBlockedStatus ]] hook allows extensions to modify properties on the `User` object. Since several of the block-related properties are made public it is theoretically possible for extensions to modify these into a state that is not compatible with any block that can actually are made. (Example: an extension could theoretically set `User::mBlock` to `null`, but `User::mBlockedBy` to a username and `User::mHideName` to `true`.) This makes blocks difficult to reason about - e.g. see T228948.
**Proposed Solution**
Now that we have a way to enforce multiple blocks, extensions that are only adding a block could do so before the `CompositeBlock` is constructed in `BlockManager::getUserBlock()`, so that their block can be added to any other blocks, rather than replacing them.
We could still allow extensions to modify the final block, but rather than allow them to alter the `User`, we could pass the array of constituent blocks, just before constructing the `CompositeBlock`.
It seems the use cases for setting these User properties are related to the [[ https://www.mediawiki.org/wiki/Manual:Hooks/GetBlockedStatus | GetBlockedStatus ]] hook, so we could reduce their visibility if we make these changes.
[] Deprecate GetBlockedStatus
[] Deprecate mBlock, mBlockedBy and mHideName as public properties on User