Skip to content

Abilities API: Replace public coerce_input() with prepare_input() - #15685

Closed
gziolo wants to merge 2 commits into
WordPress:trunkfrom
gziolo:abilities-prepare-input
Closed

gziolo wants to merge 2 commits into
WordPress:trunkfrom
gziolo:abilities-prepare-input

Conversation

@gziolo

@gziolo gziolo commented Nov 6, 2026 •

Copy link
Copy Markdown
Member

What

Input preparation is repeated in WP_Ability::execute() and the REST run controller. This PR adds a public WP_Ability::prepare_input() method that normalizes, validates, and sanitizes input in one call, returning the prepared input or the first WP_Error.

  • execute() uses prepare_input() instead of calling the three steps itself.
  • The REST run controller's check_ability_permissions() calls prepare_input() on the raw request input, replacing the private prepare_input_for_ability() helper.
  • coerce_input() is renamed to the protected sanitize_input(). Sanitizing input that was not validated can hide validation errors, so prepare_input() is now the public way to run it. coerce_input() was added in 7.2 and has not been released yet, so this is not a breaking change.

This PR is rebased onto trunk after #15684 landed and contains only the prepare_input() commit. It preserves trunk's raw-input handling and the deprecated, pass-through sanitize_input_for_ability() method.

Why

Callers currently have to run normalize_input(), validate_input(), and coerce_input() in the right order, stopping at the first error. prepare_input() centralizes that sequence for execution, REST permission checks, and integrations that call check_permissions() directly.

Documentation

The docs now refer to prepare_input() instead of listing each step. This covers the Abilities API overview, check_permissions(), execute(), and the hook docs. Tests about the sanitization step now use "sanitization" in their names, to match the method name. Tests about type conversion keep "coerce".

Testing

Verified after rebasing onto trunk:

  • npm run test:php -- --filter=Abilit passes: 1,863 tests and 6,612 assertions.
  • PHP coding standards checks pass for all five changed files.
  • npm run typecheck:php passes with no errors.

Trac ticket: https://core.trac.wordpress.org/ticket/66482, https://core.trac.wordpress.org/ticket/66383

Use of AI Tools

AI assistance: Yes
Tool(s): Claude Code, Codex
Model(s): Claude Opus 5.5; GPT-6 (Codex)
Used for: Implementation, documentation updates, and test renames, iterated on together with me. I reviewed the original code and tests. Codex assisted with the rebase, conflict resolution, verification, and PR description update.


This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

@github-actions

github-actions Bot commented Nov 6, 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.

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

Props gziolo, jorgefilipecosta, zaguiini.

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


Props Bot commands

You can trigger Props Bot actions by commenting on this PR:

  • @propsbot add <username> to give props to a GitHub user. Requires write access.
  • @propsbot remove <username> to leave a user out of the props. Requires write access.
  • @propsbot refresh to refresh this list. Adding the props-bot label works too.

@gziolo gziolo self-assigned this Nov 6, 2026
@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

Comment thread src/wp-includes/abilities-api.php Resolved

@jorgefilipecosta jorgefilipecosta left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Did some smoke testing and behavior looks good to me 👍

@zaguiini zaguiini left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Love that ✨

and returns the prepared input or the first WP_Error.

Would it be possible to return all the failed inputs? That's related to https://core.trac.wordpress.org/ticket/66436.

@github-actions

Copy link
Copy Markdown

A commit was made that fixes the Trac ticket referenced in the description of this pull request.

SVN changeset: 65368
GitHub commit: c636204

This PR will be closed, but please confirm the accuracy of this and reopen if there is more work to be done.

@github-actions github-actions Bot closed this Nov 10, 2026
@gziolo gziolo reopened this Nov 10, 2026
Adds `WP_Ability::prepare_input()`, which normalizes, validates, and sanitizes the input in one call. `execute()` and the REST run controller now use it, so they no longer repeat the three steps. Integrations that call `check_permissions()` directly can also use it.

`coerce_input()` is renamed to the protected `sanitize_input()`. It must only run on validated input, so `prepare_input()` is now the public way to reach it. `coerce_input()` was added in 7.2 and has not been released yet.

The documentation now refers to `prepare_input()` instead of listing each step. Tests about the sanitization step use "sanitization" in their names.

See #66383.
@gziolo
gziolo force-pushed the abilities-prepare-input branch from 0fc0606 to eece764 Compare November 10, 2026 04:28
@gziolo

gziolo commented Nov 10, 2026

Copy link
Copy Markdown
Member Author

@jorgefilipecosta Good catch, thanks! Both documentation points are addressed in f822e2752c.

@zaguiini A WP_Error can hold multiple failures, but the underlying schema validators currently stop at the first one. I suggest handling aggregation separately in Trac #66436; prepare_input() can pass through the combined error.

@gziolo gziolo changed the title Abilities API: Add WP_Ability::prepare_input() Abilities API: Replace public coerce_input() with prepare_input() Nov 10, 2026
wporg-sync pushed a commit that referenced this pull request Nov 10, 2026
Add a public `WP_Ability::prepare_input()` method that normalizes, validates, and sanitizes input in one call. Use it in `WP_Ability::execute()` and the REST run controller.

Rename `coerce_input()` to the protected `sanitize_input()`, so sanitization cannot run on input that was not validated. `coerce_input()` was not released yet, so this is not a breaking change.

Developed in #15685.
Follow-up to [65044], [65306].

Props gziolo, jorgefilipecosta, justlevine, zaguiini.
See #66383.
Fixes #66482.




git-svn-id: https://develop.svn.wordpress.org/trunk@65370 602fd350-edb4-49c9-b593-d223f7449a82
@github-actions

Copy link
Copy Markdown

A commit was made that fixes the Trac ticket referenced in the description of this pull request.

SVN changeset: 65370
GitHub commit: d30bfa8

This PR will be closed, but please confirm the accuracy of this and reopen if there is more work to be done.

@github-actions github-actions Bot closed this Nov 10, 2026
wporg-sync pushed a commit to WordPress/WordPress that referenced this pull request Nov 10, 2026
Add a public `WP_Ability::prepare_input()` method that normalizes, validates, and sanitizes input in one call. Use it in `WP_Ability::execute()` and the REST run controller.

Rename `coerce_input()` to the protected `sanitize_input()`, so sanitization cannot run on input that was not validated. `coerce_input()` was not released yet, so this is not a breaking change.

Developed in WordPress/wordpress-develop#15685.
Follow-up to [65044], [65306].

Props gziolo, jorgefilipecosta, justlevine, zaguiini.
See #66383.
Fixes #66482.



Built from https://develop.svn.wordpress.org/trunk@65370


git-svn-id: http://core.svn.wordpress.org/trunk@64509 1a063a9b-81f0-0310-95a4-ce76da25c4cd
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