====Problem to solve
Full site blocks are not always appropriate in all cases of user misconduct.
------
====Proposed solution
To retain constructive contributors who cause disruption on one page (e.g. contentious article page, user talk page of someone they constantly berate, etc.) we could give admins the ability to block them from editing one specific page or all articles inside a namespace.
------
====Acceptance criteria
* On Special:Block, introduce a method to block a user/IP address/IP range from a specific page or namespace
* Add a checkbox for "Block this user from the whole site". It should be checked by default. When a block is saved with this checked, the block should behave exactly as it does today.
* If the "whole site" checkbox is unchecked, the admin should be able to provide a list of pages or namespaces.
** If an admin specified a namespace to block:
*** Dropdown with existing namespaces, potentially like on RecentChanges
* Help tooltips should display for the new fields
* Block logs should display everywhere the current block displays (user page, Special:Contributions, Special:Block, Special:Log, and anywhere else)
** Log for page blocks should include `TIMESTAMP Admin-who-blocked (t|c|b) blocked BadApples (t|c) from editing the page(s) Foobar with an expiration time of N (reason) (unblock | change block)`
** Log for namespace blocks should include `TIMESTAMP Admin-who-blocked (t|c|b) blocked BadApples (t|c) from editing the namespace(s) Foobar with an expiration time of N (reason) (unblock | change block)`
** Log for both page and namespace blocks should include `TIMESTAMP Admin-who-blocked (t|c|b) blocked BadApples (t|c) from editing the page(s) Foobar and namespace(s) Foobar2 with an expiration time of N (reason) (unblock | change block)`
* Should be listed on Special:BlockList
* When a user attempts to edit an applicable page, they should see a new type of block warning message which include information on their block (reason, expiration, etc.)
* Only one block per user (like it is today) — to update the block, admins will need to modify the block.
* If a granular block is set, the checkbox for Prevent this user from editing his own talk page while blocked should be marked as disabled
* Should use a new right, assigned only to administrators
------
====Hyperlinks
* [[https://meta.wikimedia.org/wiki/2015_Community_Wishlist_Survey/Moderation_and_admin_tools#Enhanced_per-user.2C_per-article_protection_.2F_blocking|2015 Community Wishlist survey proposal]], where it received 52 support votes, and was ranked #14 out of 107 proposals.
* [[https://meta.wikimedia.org/wiki/Community_health_initiative/Per_user_page_block|Per user page block]] documentation on Meta Wiki
------
====Current wireframes
These are still being discussed on wiki, but can be followed as a general direction:
{M255}
------
====Technical Plan
- Schema Changes. The details can be found in T193449 and the patch is available in T197144.
- Add table `ipblocks_restrictions`
- Add column `ipb_sitewide` to [[ https://www.mediawiki.org/wiki/Manual:Ipblocks_table | ipblocks ]]
- API Changes
- Update [[ https://www.mediawiki.org/wiki/API:Blocks | API:Blocks ]] and [[ https://www.mediawiki.org/wiki/API:Userinfo | API:Userinfo ]](?) to list the details of the partial block T197141
- [[ https://www.mediawiki.org/wiki/API:Edit | Edit endpoints ]] will throw an appropriate error when an edit is made to a blocked page or namespace T197117
- Update [[ https://www.mediawiki.org/wiki/API:Block | API:Block ]] to allow partial blocks to be set via the API T197111
We'll allow the user (via the API or [[ https://www.mediawiki.org/wiki/Help:Blocking_users | Special:Block ]]) to set the `ipb_sitewide` flag (a boolean) and then specify the pages or namespaces they want to restrict, which will be stored in `ipblocks_restrictions`. The restrictions will need to be listed anywhere we currently list the blocks (Special:BlockList, Block Log, Contributions, etc.). We'll also enforce the block by modifying [[ https://phabricator.wikimedia.org/source/mediawiki/browse/master/includes/user/User.php;83c9efb5b9ddf52163c77dedaa710db3a3ec9d80$2283 | User::isBlockedFrom() ]] to check if the block is sitewide or not and if not to check to see if the page is on the restrictions list. Finally, we'll update the block notices the user gets so that it is page specific.
------
====FAQ
**Why make this a part of Block instead of creating another thing (i.e. "Partial Block")?**
If we were to create a new tool at `Special:PartialBlock` a lot of the existing functionality between Block and Partial Block would be duplicated. There would not only be a separate page to create the block, but also a separate list of blocks `SpecialPartialBlockList` as well as a separate log. New, effectively duplicate API endpoints would need to be created to create and list partial blocks. Lastly, there would also need to be distinct block notices for users who are partially blocked. Not only is this a lot of duplication of existing functionality, it is confusing for new admins to have to different pages to //block// a user.
**Why make this part of core and not a new extension?**
Effectively, because //Block// is in core. The UX should be well integrated into the existing //Block// workflow. Alternatively, it is certainly possible to implement this feature as an extension, but many new hooks will need to be created in order to make the necessary modifications to the existing //Block// workflow. Another alternative would be to pull //Block// out of core completely into its own extension, but that is outside the scope of this issue.