PHPCS: Allowlist custom capabilities instead of disabling the sniff#583
PHPCS: Allowlist custom capabilities instead of disabling the sniff#583obenland wants to merge 6 commits intoWordPress:trunkfrom
Conversation
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>
|
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.
|
|
||
| // Bail if user isn't a moderator. | ||
| if ( ! user_can( $user->ID, 'photos_moderator' ) ) { | ||
| if ( empty( $caps['edit_photos'] ) ) { |
There was a problem hiding this comment.
I think this needs a user_can(), because super-admin roles don't have the caps.
There was a problem hiding this comment.
Hmmm.. actually... this is a user_has_cap filter.. Using user_can and friends in that is discouraged in cap filters.. due to loops..
I think the proper check here would be to be either requiring a cap by appending to $caps, or appending do_not_allow to block.. or.. something.. else...
There was a problem hiding this comment.
I suppose it depends on how we want this to behave. It sets edit_photos to false when the photo in question is the moderator's own photo.
If we want super admins to be able to edit their own submissions we'd append a || is_super_admin( $user->ID ) check to bail. Otherwise a && ! is_super_admin( $user->ID ) to apply to them, too?
...g/public_html/wp-content/plugins/plugin-directory/admin/tools/class-elasticsearch-status.php
Show resolved
Hide resolved
| <!-- Custom capabilities used across the WordPress.org environment. --> | ||
| <rule ref="WordPress.WP.Capabilities"> |
There was a problem hiding this comment.
I'm not really a fan of this style of nitty-gritty capability listing.. but I'm not veto'ing this.
Perhaps we can do a middle-ground of warning severity or notice severity, and not error?
Let's also document it here that PRs can update the list as needed, and this isn't a strict requirement, rather just to catch those typos.
| <!-- Custom capabilities used across the WordPress.org environment. --> | |
| <rule ref="WordPress.WP.Capabilities"> | |
| <!-- Custom capabilities used across the WordPress.org environment. --> | |
| <!-- Please note: Using custom capabilities is allowed, just document them here please! --> | |
| <rule ref="WordPress.WP.Capabilities"> |
…owlist. Co-Authored-By: Claude Opus 4.6 (1M context) <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