Skip to content

PHPCS: Allowlist custom capabilities instead of disabling the sniff - #583

Open
obenland wants to merge 7 commits into
WordPress:trunkfrom
obenland:fix/phpcs-custom-capabilities
Open

PHPCS: Allowlist custom capabilities instead of disabling the sniff#583
obenland wants to merge 7 commits into
WordPress:trunkfrom
obenland:fix/phpcs-custom-capabilities

Conversation

@obenland

Copy link
Copy Markdown
Member

Summary

  • Replace the blanket <severity>0</severity> override on WordPress.WP.Capabilities.Unknown with an explicit allowlist of all custom capabilities used across the codebase, grouped by plugin.
  • Fix four capability bugs surfaced by enabling the sniff:
    • Plugin Directory: ES Status tool used the role name plugin_admin instead of a capability — replaced with plugin_approve.
    • Plugin Directory: Comment row actions checked manage_comments, which is not a WordPress capability — replaced with moderate_comments.
    • Photo Directory: Moderation used the role name photos_moderator instead of a capability — replaced with edit_photos.
    • BuddyPress: Admin redirect checked four role names (contributor, author, editor, administrator) instead of capabilities — replaced with a single edit_posts check.

Test plan

  • Run composer install && vendor/bin/phpcs --sniffs=WordPress.WP.Capabilities . and confirm no warnings or errors
  • Verify the Plugin Directory ES Index Status tool is still accessible to plugin admins
  • Verify Plugin Directory internal note comment actions still work for reviewers
  • Verify Photo Directory moderation capabilities still work for photo moderators
  • Verify BuddyPress admin redirect still allows contributors and above into wp-admin

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings March 31, 2026 22:17
@github-actions

github-actions Bot commented Mar 31, 2026

Copy link
Copy Markdown

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 props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props obenland, dd32.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@obenland

Copy link
Copy Markdown
Member Author

@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.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_capabilities allowlist (grouped by subsystem).
  • Fix Plugin Directory capability checks by replacing the non-capability plugin_admin role checks with the plugin_approve capability.
  • 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.

Comment thread wordpress.org/public_html/wp-content/plugins/photo-directory/inc/moderation.php Outdated
Comment thread phpcs.xml.dist
obenland and others added 5 commits August 6, 2026 20:37
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>
@obenland
obenland force-pushed the fix/phpcs-custom-capabilities branch from 6ee71cb to c1ad7ec Compare August 7, 2026 01:38
obenland and others added 2 commits August 6, 2026 20:50
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>
obenland added a commit to obenland/wordpress.org that referenced this pull request Aug 7, 2026
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants