Skip to content

Comments: Add a capabilities object to comment types#52

Open
adamsilverstein wants to merge 3 commits into
feature/register-comment-typefrom
feature/comment-type-caps
Open

Comments: Add a capabilities object to comment types#52
adamsilverstein wants to merge 3 commits into
feature/register-comment-typefrom
feature/comment-type-caps

Conversation

@adamsilverstein

Copy link
Copy Markdown
Owner

Description

Adds a capabilities object to comment types, modeled on WP_Post_Type and get_post_type_capabilities(). Registered comment types can now describe their own read/edit/delete/moderate capabilities, which is a prerequisite for per-type permission handling on the #35214 tracking ticket (and for exposing capabilities through the REST endpoint).

What it adds

  • A capability_type registration argument (default 'comment'; may be an array like array( 'story', 'stories' ) for an explicit plural).
  • A capabilities registration argument to override individual generated capabilities.
  • A WP_Comment_Type::$cap object, built by the new get_comment_type_capabilities() helper.
register_comment_type( 'review', array( 'capability_type' => 'review' ) );

$obj = get_comment_type_object( 'review' );
$obj->cap->edit_comments;      // 'edit_reviews'
$obj->cap->moderate_comments;  // 'moderate_reviews'
$obj->cap->edit_comment;       // 'edit_review' (meta cap)

Non-breaking by design

This is advisory metadata only. map_meta_cap() is intentionally left unchanged, so there is no behavior change to comment moderation or editing. The built-in comment type resolves to the existing edit_comment (meta) and moderate_comments (primitive) capabilities, so current behavior is preserved exactly.

Wiring these capabilities into map_meta_cap() enforcement is deliberately left to a follow-up, so the capability model can be reviewed and agreed on before touching the live permission path.

Scope / boundary

Stacked on WordPress#12311 (the register_comment_type() API) and targets that branch; it will be retargeted to trunk once WordPress#12311 lands. Complements the REST endpoint (#51, also stacked on WordPress#12311) and the default_excluded_comment_types query filter (WordPress#12310 / #65537).

Testing

$ phpunit --group comment
OK (590 tests, 1459 assertions)

Capability/meta-cap suites also pass unchanged (753 tests), confirming no enforcement-path regression. PHPCS and PHPStan are clean on the changed files.

See #35214.

@github-actions

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

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

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 183cfd66-8f59-446f-a7f6-c3cc49fd8276

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/comment-type-caps

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@adamsilverstein

Copy link
Copy Markdown
Owner Author

Follow-up: capability enforcement via map_meta_cap()

This PR intentionally keeps the cap object advisory. Proposing the lowest-risk path to actual enforcement, mirroring register_post_type():

  • Opt-in. Default capability_type => 'comment' stays byte-for-byte identical (editing still derives from the parent post's edit_post; moderation still uses the moderate_comments primitive). Only types declaring a non-default capability_type / explicit capabilities route through the new handling.
  • Map, don't grant. New per-type meta caps (read_comment / edit_comment / delete_comment / moderate_comment) map to the type's primitives via map_meta_cap(); sites grant the primitives to roles, exactly as with custom post types. No role (admin included) is silently locked out because the default path is unchanged.
  • Stage the call-site rerouting (edit → moderation → delete) instead of one audit-heavy change, so each surface gets a focused security review.

One question to settle before coding: do custom comment types keep deriving edit permission from the parent post, or get a permission boundary independent of it? That is the substantive design fork (the comment:19 concern). Happy to write this up on Trac #35214 if the direction looks right.

Give `WP_Comment_Type` a `cap` object built from new `capability_type` and
`capabilities` registration arguments, modeled on `WP_Post_Type` and
`get_post_type_capabilities()`. A new `get_comment_type_capabilities()` helper
builds the capability strings from the `capability_type` base (default
'comment'), so a registered type can describe its own read, edit, delete, and
moderate capabilities.

This is advisory metadata only: `map_meta_cap()` is intentionally not changed,
so there is no behavior change. The built-in `comment` type resolves to the
existing `edit_comment` and `moderate_comments` capabilities, preserving current
behavior. Enforcing per-type capabilities through `map_meta_cap()` is left to a
follow-up so the capability model can be agreed on first.

See #35214.
Cover the new `capability_type`/`capabilities` arguments and the
`get_comment_type_capabilities()` helper: default and custom capability types,
array capability types with explicit plurals, the `capabilities` override, that
the input `capabilities` array is not retained as a property, and that the
built-in `comment` type stays backward compatible with the existing core
capabilities.

See #35214.
The existing tests spot-checked individual generated capabilities;
read_comment, moderate_comment, and delete_comments were never asserted.
Add a test pinning the complete meta and primitive capability set built
by get_comment_type_capabilities() from a string base, plus a direct
test of the array capability_type form (explicit plural).

See #35214.
@adamsilverstein adamsilverstein force-pushed the feature/comment-type-caps branch from d2ee949 to c4978f3 Compare June 25, 2026 06:32
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.

1 participant