PHPCS: Allowlist custom capabilities instead of disabling the sniff - #583
PHPCS: Allowlist custom capabilities instead of disabling the sniff#583obenland wants to merge 7 commits into
Conversation
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
@dd32 Wanted to give you a chance to veto. It's a long allowlist, but it enables catching misuses like the other changes in this PR. |
There was a problem hiding this comment.
Pull request overview
This PR enables the WordPress.WP.Capabilities.Unknown sniff by replacing the prior blanket suppression with an explicit allowlist of custom capabilities, and fixes several real capability/role mismatches that the sniff surfaces.
Changes:
- Replace the PHPCS suppression of unknown capabilities with a curated
custom_capabilitiesallowlist (grouped by subsystem). - Fix Plugin Directory capability checks by replacing the non-capability
plugin_adminrole checks with theplugin_approvecapability. - Fix several incorrect capability/role checks (
manage_comments,photos_moderator, and BuddyPress role-name checks) by switching to appropriate WordPress capabilities.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/tools/class-elasticsearch-status.php |
Switch ES Status tool access checks from a role name to the plugin_approve capability (menu + render + AJAX). |
wordpress.org/public_html/wp-content/plugins/plugin-directory/admin/class-customizations.php |
Fix internal-note comment row actions gating by using moderate_comments (valid WP cap). |
wordpress.org/public_html/wp-content/plugins/photo-directory/inc/moderation.php |
Replace role-name moderation check with a capability-based check (edit_photos) for moderator logic. |
phpcs.xml.dist |
Replace disabling the capability sniff with an explicit allowlist of custom capabilities for the environment. |
buddypress.org/public_html/wp-content/plugins/buddypress-org/buddypress-dot-org.php |
Replace role-name checks with a single edit_posts capability check for wp-admin redirect UX behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Replace the blanket severity override for WordPress.WP.Capabilities.Unknown with an explicit allowlist of all custom capabilities used across the codebase. This also fixes two capability bugs surfaced by enabling the sniff: - Plugin Directory ES Status tool used the role name `plugin_admin` instead of a capability. Replace with `plugin_approve`, which is the distinguishing capability for the plugin admin role. - Plugin Directory comment row actions checked `manage_comments`, which is not a WordPress capability. Replace with `moderate_comments`. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add singular theme caps (suspend_theme, reinstate_theme) and bbPress caps (bbp_forums_admin, edit_topic, edit_reply, read_topic) to the allowlist. - Photo Directory used the role name photos_moderator instead of a capability. Replace with edit_photos. - BuddyPress checked four role names instead of capabilities in the admin redirect. Replace with a single edit_posts check, which all contributors and above have. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…p filter. Calling user_can() for edit_photos inside a user_has_cap filter that handles edit_photos would cause infinite recursion. Check the allcaps array directly instead. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…owlist. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6ee71cb to
c1ad7ec
Compare
Checking the raw capabilities array misses users whose moderation caps are granted dynamically at a later user_has_cap priority, like caped users. user_can() runs the full capability pipeline so those grants apply. The nested filter re-entry is safe: the inner check carries no post context and bails at the $args[2] guard before doing anything. This restores the original user_can() pattern, just with a registered capability instead of the photos_moderator role name that the Capabilities sniff flags. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CI only enforces the ruleset on lines a branch touches and on new files, so sniff exclusions only ever shield newly written code. Remove them all, keeping just the deliberate deviations: direct/meta DB queries (custom tables are the architecture here), the I18nTextDomainFixer utility, short array syntax, and unknown capabilities pending the allowlist in PR WordPress#583. Supersedes PR WordPress#714, which proposed the same standard via a second config file; a single config can't drift apart from what CI enforces and keeps local lint results identical to CI. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Summary
<severity>0</severity>override onWordPress.WP.Capabilities.Unknownwith an explicit allowlist of all custom capabilities used across the codebase, grouped by plugin.plugin_admininstead of a capability — replaced withplugin_approve.manage_comments, which is not a WordPress capability — replaced withmoderate_comments.photos_moderatorinstead of a capability — replaced withedit_photos.contributor,author,editor,administrator) instead of capabilities — replaced with a singleedit_postscheck.Test plan
composer install && vendor/bin/phpcs --sniffs=WordPress.WP.Capabilities .and confirm no warnings or errors🤖 Generated with Claude Code