Repository navigation
Add core/settings-update ability - #764
jorgefilipecosta wants to merge 57 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 If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
✅ WordPress Plugin Check Report
📊 ReportAll checks passed! No errors or warnings found. 🤖 Generated by WordPress Plugin Check Action • Learn more about Plugin Check |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #764 +/- ##
=============================================
+ Coverage 81.67% 82.28% +0.60%
- Complexity 3103 3407 +304
=============================================
Files 129 136 +7
Lines 12334 13288 +954
=============================================
+ Hits 10074 10934 +860
- Misses 2260 2354 +94
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Bumps the github-actions-updates group with 2 updates: [actions/checkout](https://github.com/actions/checkout) and [softprops/action-gh-release](https://github.com/softprops/action-gh-release). Updates `actions/checkout` from 6.0.3 to 7.0.0 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/actions/checkout/releases">actions/checkout's releases</a>.</em></p> <blockquote> <h2>v7.0.0</h2> <h2>What's Changed</h2> <ul> <li>block checking out fork pr for pull_request_target and workflow_run by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li> <li>Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the minor-actions-dependencies group across 1 directory by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2458">actions/checkout#2458</a></li> <li>Bump flatted from 3.3.1 to 3.4.2 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2460">actions/checkout#2460</a></li> <li>Bump js-yaml from 4.1.0 to 4.2.0 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2461">actions/checkout#2461</a></li> <li>Bump <code>@actions/core</code> and <code>@actions/tool-cache</code> and Remove uuid by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2459">actions/checkout#2459</a></li> <li>upgrade module to esm and update dependencies by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2463">actions/checkout#2463</a></li> <li>Bump the minor-npm-dependencies group across 1 directory with 3 updates by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2462">actions/checkout#2462</a></li> <li>getting ready for checkout v7 release by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2464">actions/checkout#2464</a></li> <li>update error wording by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2467">actions/checkout#2467</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> made their first contribution in <a href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/actions/checkout/compare/v6.0.3...v7.0.0">https://github.com/actions/checkout/compare/v6.0.3...v7.0.0</a></p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/actions/checkout/blob/main/CHANGELOG.md">actions/checkout's changelog</a>.</em></p> <blockquote> <h1>Changelog</h1> <h2>v7.0.0</h2> <ul> <li>Block checking out fork PR for pull_request_target and workflow_run by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2454">actions/checkout#2454</a></li> <li>Bump actions/publish-immutable-action from 0.0.3 to 0.0.4 in the minor-actions-dependencies group across 1 directory by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2458">actions/checkout#2458</a></li> <li>Bump flatted from 3.3.1 to 3.4.2 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2460">actions/checkout#2460</a></li> <li>Bump js-yaml from 4.1.0 to 4.2.0 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2461">actions/checkout#2461</a></li> <li>Bump <code>@actions/core</code> and <code>@actions/tool-cache</code> and Remove uuid by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2459">actions/checkout#2459</a></li> <li>upgrade module to esm and update dependencies by <a href="https://github.com/aiqiaoy"><code>@aiqiaoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2463">actions/checkout#2463</a></li> <li>Bump the minor-npm-dependencies group across 1 directory with 3 updates by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/actions/checkout/pull/2462">actions/checkout#2462</a></li> </ul> <h2>v6.0.3</h2> <ul> <li>Fix checkout init for SHA-256 repositories by <a href="https://github.com/yaananth"><code>@yaananth</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2439">actions/checkout#2439</a></li> <li>fix: expand merge commit SHA regex and add SHA-256 test cases by <a href="https://github.com/yaananth"><code>@yaananth</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2414">actions/checkout#2414</a></li> </ul> <h2>v6.0.2</h2> <ul> <li>Fix tag handling: preserve annotations and explicit fetch-tags by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2356">actions/checkout#2356</a></li> </ul> <h2>v6.0.1</h2> <ul> <li>Add worktree support for persist-credentials includeIf by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2327">actions/checkout#2327</a></li> </ul> <h2>v6.0.0</h2> <ul> <li>Persist creds to a separate file by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2286">actions/checkout#2286</a></li> <li>Update README to include Node.js 24 support details and requirements by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2248">actions/checkout#2248</a></li> </ul> <h2>v5.0.1</h2> <ul> <li>Port v6 cleanup to v5 by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2301">actions/checkout#2301</a></li> </ul> <h2>v5.0.0</h2> <ul> <li>Update actions checkout to use node 24 by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2226">actions/checkout#2226</a></li> </ul> <h2>v4.3.1</h2> <ul> <li>Port v6 cleanup to v4 by <a href="https://github.com/ericsciple"><code>@ericsciple</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2305">actions/checkout#2305</a></li> </ul> <h2>v4.3.0</h2> <ul> <li>docs: update README.md by <a href="https://github.com/motss"><code>@motss</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1971">actions/checkout#1971</a></li> <li>Add internal repos for checking out multiple repositories by <a href="https://github.com/mouismail"><code>@mouismail</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1977">actions/checkout#1977</a></li> <li>Documentation update - add recommended permissions to Readme by <a href="https://github.com/benwells"><code>@benwells</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2043">actions/checkout#2043</a></li> <li>Adjust positioning of user email note and permissions heading by <a href="https://github.com/joshmgross"><code>@joshmgross</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2044">actions/checkout#2044</a></li> <li>Update README.md by <a href="https://github.com/nebuk89"><code>@nebuk89</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2194">actions/checkout#2194</a></li> <li>Update CODEOWNERS for actions by <a href="https://github.com/TingluoHuang"><code>@TingluoHuang</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2224">actions/checkout#2224</a></li> <li>Update package dependencies by <a href="https://github.com/salmanmkc"><code>@salmanmkc</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/2236">actions/checkout#2236</a></li> </ul> <h2>v4.2.2</h2> <ul> <li><code>url-helper.ts</code> now leverages well-known environment variables by <a href="https://github.com/jww3"><code>@jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1941">actions/checkout#1941</a></li> <li>Expand unit test coverage for <code>isGhes</code> by <a href="https://github.com/jww3"><code>@jww3</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1946">actions/checkout#1946</a></li> </ul> <h2>v4.2.1</h2> <ul> <li>Check out other refs/* by commit if provided, fall back to ref by <a href="https://github.com/orhantoy"><code>@orhantoy</code></a> in <a href="https://redirect.github.com/actions/checkout/pull/1924">actions/checkout#1924</a></li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/actions/checkout/commit/9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0"><code>9c091bb</code></a> update error wording (<a href="https://redirect.github.com/actions/checkout/issues/2467">#2467</a>)</li> <li><a href="https://github.com/actions/checkout/commit/1044a6dea927916f2c38ba5aeffbc0a847b1221a"><code>1044a6d</code></a> getting ready for checkout v7 release (<a href="https://redirect.github.com/actions/checkout/issues/2464">#2464</a>)</li> <li><a href="https://github.com/actions/checkout/commit/f0282184c7ce73ab54c7e4ab5a617122602e575f"><code>f028218</code></a> Bump the minor-npm-dependencies group across 1 directory with 3 updates (<a href="https://redirect.github.com/actions/checkout/issues/2462">#2462</a>)</li> <li><a href="https://github.com/actions/checkout/commit/d914b262ffc244530a203ab40decab34c3abf34d"><code>d914b26</code></a> upgrade module to esm and update dependencies (<a href="https://redirect.github.com/actions/checkout/issues/2463">#2463</a>)</li> <li><a href="https://github.com/actions/checkout/commit/537c7ef99cef6e5ddb5e7ff5d16d14510503801d"><code>537c7ef</code></a> Bump <code>@actions/core</code> and <code>@actions/tool-cache</code> and Remove uuid (<a href="https://redirect.github.com/actions/checkout/issues/2459">#2459</a>)</li> <li><a href="https://github.com/actions/checkout/commit/130a169078a413d3a5246a393625e8e742f387f6"><code>130a169</code></a> Bump js-yaml from 4.1.0 to 4.2.0 (<a href="https://redirect.github.com/actions/checkout/issues/2461">#2461</a>)</li> <li><a href="https://github.com/actions/checkout/commit/7d09575332117a40b46e5e020664df234cd416f3"><code>7d09575</code></a> Bump flatted from 3.3.1 to 3.4.2 (<a href="https://redirect.github.com/actions/checkout/issues/2460">#2460</a>)</li> <li><a href="https://github.com/actions/checkout/commit/0f9f3aa320cb53abeb534aeb54048075d9697a0e"><code>0f9f3aa</code></a> Bump actions/publish-immutable-action (<a href="https://redirect.github.com/actions/checkout/issues/2458">#2458</a>)</li> <li><a href="https://github.com/actions/checkout/commit/f9e715a95fcd1f9253f77dd28f11e88d2d6460c7"><code>f9e715a</code></a> block checking out fork pr for pull_request_target and workflow_run (<a href="https://redirect.github.com/actions/checkout/issues/2454">#2454</a>)</li> <li>See full diff in <a href="https://github.com/actions/checkout/compare/df4cb1c069e1874edd31b4311f1884172cec0e10...9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0">compare view</a></li> </ul> </details> <br /> Updates `softprops/action-gh-release` from 3.0.0 to 3.0.1 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/softprops/action-gh-release/releases">softprops/action-gh-release's releases</a>.</em></p> <blockquote> <h2>v3.0.1</h2> <h2>3.0.1</h2> <ul> <li>maintenance release with updated dependencies</li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md">softprops/action-gh-release's changelog</a>.</em></p> <blockquote> <h2>3.0.1</h2> <ul> <li>maintenance release with updated dependencies</li> </ul> <h2>3.0.0</h2> <p><code>3.0.0</code> is a major release that moves the action runtime from Node 20 to Node 24. Use <code>v3</code> on GitHub-hosted runners and self-hosted fleets that already support the Node 24 Actions runtime. If you still need the last Node 20-compatible line, stay on <code>v2.6.2</code>.</p> <h2>What's Changed</h2> <h3>Other Changes 🔄</h3> <ul> <li>Move the action runtime and bundle target to Node 24</li> <li>Update <code>@types/node</code> to the Node 24 line and allow future Dependabot updates</li> <li>Keep the floating major tag on <code>v3</code>; <code>v2</code> remains pinned to the latest <code>2.x</code> release</li> </ul> <h2>2.6.2</h2> <h2>What's Changed</h2> <h3>Other Changes 🔄</h3> <ul> <li>chore(deps): bump picomatch from 4.0.3 to 4.0.4 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/softprops/action-gh-release/pull/775">softprops/action-gh-release#775</a></li> <li>chore(deps): bump brace-expansion from 5.0.4 to 5.0.5 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/softprops/action-gh-release/pull/777">softprops/action-gh-release#777</a></li> <li>chore(deps): bump vite from 8.0.0 to 8.0.5 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/softprops/action-gh-release/pull/781">softprops/action-gh-release#781</a></li> </ul> <h2>2.6.1</h2> <p><code>2.6.1</code> is a patch release focused on restoring linked discussion thread creation when <code>discussion_category_name</code> is set. It fixes <code>[#764](https://github.com/softprops/action-gh-release/issues/764)</code>, where the draft-first publish flow stopped carrying the discussion category through the final publish step.</p> <p>If you still hit an issue after upgrading, please open a report with the bug template and include a minimal repro or sanitized workflow snippet where possible.</p> <h2>What's Changed</h2> <h3>Bug fixes 🐛</h3> <ul> <li>fix: preserve discussion category on publish by <a href="https://github.com/chenrui333"><code>@chenrui333</code></a> in <a href="https://redirect.github.com/softprops/action-gh-release/pull/765">softprops/action-gh-release#765</a></li> </ul> <h2>2.6.0</h2> <p><code>2.6.0</code> is a minor release centered on <code>previous_tag</code> support for <code>generate_release_notes</code>, which lets workflows pin GitHub's comparison base explicitly instead of relying on the default range. It also includes the recent concurrent asset upload recovery fix, a <code>working_directory</code> docs sync, a checked-bundle freshness guard for maintainers, and clearer immutable-prerelease guidance where GitHub platform behavior imposes constraints on how prerelease asset uploads can be published.</p> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/softprops/action-gh-release/commit/718ea10b132b3b2eba29c1007bb80653f286566b"><code>718ea10</code></a> release 3.0.1</li> <li><a href="https://github.com/softprops/action-gh-release/commit/f1a938b9d84ca9b770d0d8dfeb3e7285fe261e63"><code>f1a938b</code></a> chore(deps): bump esbuild from 0.28.0 to 0.28.1 (<a href="https://redirect.github.com/softprops/action-gh-release/issues/802">#802</a>)</li> <li><a href="https://github.com/softprops/action-gh-release/commit/0066ead0de7252b4876b36b5357fc3974619d36a"><code>0066ead</code></a> chore(deps): bump vite from 8.0.14 to 8.0.16 (<a href="https://redirect.github.com/softprops/action-gh-release/issues/806">#806</a>)</li> <li><a href="https://github.com/softprops/action-gh-release/commit/dc643cac6252aaa00c9b0b6c940d489cd7bf6b23"><code>dc643ca</code></a> chore(deps): bump the npm group with 3 updates (<a href="https://redirect.github.com/softprops/action-gh-release/issues/805">#805</a>)</li> <li><a href="https://github.com/softprops/action-gh-release/commit/85ee99b6b20742a3823a8a289ee5e6ceab44e8aa"><code>85ee99b</code></a> chore(deps): bump actions/checkout in the github-actions group (<a href="https://redirect.github.com/softprops/action-gh-release/issues/804">#804</a>)</li> <li><a href="https://github.com/softprops/action-gh-release/commit/9ed3cf9a6863b31f005d951c8d19de20628cf4eb"><code>9ed3cf9</code></a> chore(deps): bump the npm group with 2 updates (<a href="https://redirect.github.com/softprops/action-gh-release/issues/800">#800</a>)</li> <li><a href="https://github.com/softprops/action-gh-release/commit/3efcac8951299998593f871640ea8059d6818655"><code>3efcac8</code></a> chore(deps): bump the npm group with 3 updates (<a href="https://redirect.github.com/softprops/action-gh-release/issues/798">#798</a>)</li> <li><a href="https://github.com/softprops/action-gh-release/commit/05d6b9164aa74958de40b0179d6a773112fcdc7f"><code>05d6b91</code></a> chore(deps): bump brace-expansion from 5.0.5 to 5.0.6 (<a href="https://redirect.github.com/softprops/action-gh-release/issues/797">#797</a>)</li> <li><a href="https://github.com/softprops/action-gh-release/commit/403a5240f3837fa857f642062e05aad6bb3391ca"><code>403a524</code></a> chore(deps): bump <code>@types/node</code> from 24.12.2 to 24.12.3 in the npm group (<a href="https://redirect.github.com/softprops/action-gh-release/issues/796">#796</a>)</li> <li><a href="https://github.com/softprops/action-gh-release/commit/437e073e786973c6b6af97d9e445c41ae43b1d29"><code>437e073</code></a> chore(deps): bump the npm group with 4 updates (<a href="https://redirect.github.com/softprops/action-gh-release/issues/792">#792</a>)</li> <li>Additional commits viewable in <a href="https://github.com/softprops/action-gh-release/compare/b4309332981a82ec1c5618f44dd2e27cc8bfbfda...718ea10b132b3b2eba29c1007bb80653f286566b">compare view</a></li> </ul> </details> <br /> Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore <dependency name> major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore <dependency name> minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore <dependency name>` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore <dependency name>` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore <dependency name> <ignore condition>` will remove the ignore condition of the specified dependency and ignore conditions </details> <!-- wp-playground-preview:start --> <a href="https://playground.wordpress.net?blueprint-url=data:application/json,%7B%22preferredVersions%22%3A%7B%22wp%22%3A%22latest%22%7D%2C%22steps%22%3A%5B%7B%22step%22%3A%22installPlugin%22%2C%22pluginData%22%3A%7B%22resource%22%3A%22url%22%2C%22url%22%3A%22https%3A%2F%2Fgithub.com%2FWordPress%2Fai%2Freleases%2Fdownload%2Fci-artifacts%2Fpr-780-ee5cd01f0ec6e8d122b0d58ced3e253b6eb3938d.zip%22%7D%7D%5D%7D" target="_blank" rel="noopener noreferrer"> <img src="https://raw.githubusercontent.com/adamziel/playground-preview/refs/heads/trunk/assets/playground-preview-button.svg" alt="Open WordPress Playground Preview" width="220" height="57" /> </a> <!-- wp-playground-preview:end --> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
|
I'd like to see #863 land alongside this specific PR (and any others that aren't explicitly read abilities), to help ensure folks enabling these sorts of abilities are doing so knowingly. |
68d5383 to
1174887
Compare
Port the core change in WordPress/wordpress-develop#12141 (30742fc248). The input schema validates `fields` with rest_is_array(), which also accepts a comma-separated string, but execute_get_settings() replaced anything other than an array with an empty one, so a PHP caller that passed 'title,posts_per_page' got every setting back. REST requests were not affected, because the run endpoint converts the input to the schema types first. Normalize the list with rest_sanitize_array().
Port the core docs change in WordPress/wordpress-develop#12141 (4620fbcaed). An array replaces the show_in_rest name and schema entirely, so a setting that only sets a name for abilities also drops its REST schema, such as an email format. Say so where Show_In_Abilities describes the values it can set.
Port the core test in WordPress/wordpress-develop#12141 (f5cf4af483). show_in_abilities => true reuses the show_in_rest name and schema, so guard the opt-in rule next to it: a setting shown in the REST API without show_in_abilities is not exposed.
… exposed Port the core docs change in WordPress/wordpress-develop#12141 (89ca6e70f4). The abilities registry can initialize while init is still running, for example when a plugin uses it at an earlier init priority, so the docs were wrong to call registering a setting on init reliable. Say that settings registered after the abilities register are not exposed, and drop the comments that only repeat that the exposed settings are computed once.
Port the core change in WordPress/wordpress-develop#12141 (a4e7ea0948). It does not: it reads values with a plain get_option() call, without the rest_pre_get_setting filter or the schema default that /wp/v2/settings passes, and it leaves out a value the endpoint answers with null. Describe what the ability does instead.
Port the core change in WordPress/wordpress-develop#12141 (f454c10bbf). PHP turns a numeric array key, such as a setting named 123, into an integer. The fields enum then listed the integer, so input validation rejected the name passed as a string, and the strict in_array() check did not match it either. Cast the names to strings, and test with a numeric setting name. core/settings-update builds its answer from the keys of the settings it wrote, which are integers for such names, so pass them to core/settings-get as strings too. Without that, the string check would leave a numeric setting out of the answer.
Port the core change in WordPress/wordpress-develop#12141 (a999491872). Stored values were only validated before sanitizing, but rest_sanitize_value_from_schema() can turn a valid value into one the schema rejects. For example, sanitize_text_field() turns the email %ab@x.co into @x.co. Output validation then failed the whole call instead of leaving out that one setting. Validate the sanitized value too.
The comment above the schema checks in execute_get_settings() had a sentence about core/settings-update resets, the only difference from core's method besides the @SInCE lines, and it carried no Plugin: marker. Drop it.
null deletes the stored value. Among the core settings only language, use_smilies and posts_per_page register a default, so for the others a null left the setting without a value: the site title, the date format or the front page setting read as false, and both abilities then left the setting out. The description promised that the setting falls back to its default. Add null to the type, and to any enum, only for a setting with a registered default, so the input schema shows which settings can be reset and the Abilities API rejects a null for the others. The settings endpoint accepts null for every setting.
rest_sanitize_value_from_schema() can turn a valid value into one the
schema rejects: sanitize_text_field() turns the email %ab@x.co into
@x.co. The ability stored that value, and since core/settings-get now
leaves out such values, the answer was {} with nothing to say why.
Validate the sanitized value too, and refuse it with
settings_invalid_param before any setting is written. The settings
endpoint stores it.
WordPress stores false as '', which the boolean schema rejects. A null for a boolean turned off in an earlier request was then refused with settings_invalid_stored_value, although core/settings-get reads the setting as false, so a client never sees an invalid value to protect. Read the stored value the way core/settings-get does before checking it. The settings endpoint refuses that null, since it answers null for the setting.
A show_in_abilities (or show_in_rest) name that is not a string, such as an array, was used as an array key, which is a fatal error while the abilities register, so one bad registration broke every ability. develop checked the name with is_string(). Use the option name instead, as for an empty name. Core's WP_Abilities_Settings, and the settings endpoint, fail the same way, so this is marked as a plugin difference.
WP_UnitTestCase backs up $wp_actions once and restores it after every test, so the two tests that set the rest_api_init count no longer save and restore it themselves.
rest_validate_value_from_schema() ignores an empty enum, so a setting whose schema has `enum => array()`, such as a list computed when the setting registers that came out empty, accepts any value through core/settings-get and the settings endpoint. For a setting with a default, update_value_schema() appended null to it, which left `enum => array( null )`, so the ability refused every value but null. Add null only to an enum that is not empty.
…alue The comment said the check keeps a client that sends a response back from deleting values that fail validation. core/settings-get never answers null, it leaves such values out, so that only holds for answers from the settings endpoint, whose setting names the abilities now share. Say so, and note that a repeated null can be refused once the stored value is gone, since get_option() is passed false as the default.
The input schema alone kept url and email read-only and refused null
for a setting without a default. A wp_ability_validate_input filter
can skip that validation, and then {"url": ...} wrote siteurl before
the output check failed, a null deleted default_ping_status, and an
input with only unknown names answered with every setting, since an
empty `fields` filter means all of them.
Skip read-only settings in the write loop, check each sanitized value
against the input schema rather than the setting's schema, and answer
with no setting when nothing was written.
A null deleted the stored value, as the settings endpoint does, so the
setting fell back to its registered default. That default only applies
in requests that register the setting, and core registers its own
settings only in REST and abilities requests. After
{"posts_per_page": null}, the ability answered 10 while other requests
read false and showed one post per page, and sending 10 again stored
nothing, since update_option() skips a value that matches the
registered default when no value is stored.
Delete the stored value, then store the registered default, so every
request reads it. The delete comes first because sanitize_option()
turns a language that is not installed, such as the en_US default, into
the current value. Also store a value that update_option() skips that
way.
The stored-value check read the value with false as the default, as the settings endpoint does, so a setting with no stored value failed validation and null was refused with a 500: language on a site without a WPLANG row, or posts_per_page after the endpoint's null deleted it. Since null now stores the default, that refusal blocked the very reset that repairs such a setting. Read a missing value as the registered default, as core/settings-get and the endpoint answer it. A stored value that fails validation is still refused.
The fallback after update_option() added the value whenever no value
was stored afterwards, including a value update_option() refused on
purpose: a pre_update_option_{$option} filter that turned the update
back was bypassed, and a language that is not installed left a new
en_US row where the settings endpoint stores nothing.
Add the value only when it matches the registered default, the one case
where update_option() stores nothing because no value is stored.
…ema. `execute()` validates the whole output against the output schema, so one stored value that does not match its setting's schema (for example an out-of-enum `default_ping_status`) made the entire call fail. Validate each cast value against its schema and leave out only the ones it rejects, as WordPress/ai#764 does for the plugin's copy of the ability.
With nothing exposed, the ability could not return anything and its schemas would carry empty enums and properties. Compute the exposed settings in register() and register nothing when there are none, as WordPress/ai#764 does for the plugin's copy of the ability.
The AI plugin named the write ability `core/settings-update` (see WordPress/ai#764), so update the comments that still called it `core/manage-settings`.
An empty PHP array is encoded as `[]`, so an ability whose output schema describes an object, such as `core/settings-get` when its filters match no setting, answered with a JSON array. When the output schema describes an object, send an empty object instead, so the response matches the schema. PHP callers still receive the plain array. Suggested in WordPress/ai#764, where `core/settings-update` worked around it with an `(object)` cast.
"Settings Get" follows the ability name but does not read as a label. The other core abilities start with the verb, as in "Get Site Information". The AI plugin uses the same label (see WordPress/ai#764).
core/settings-update ability
- Name the class members like the users and content classes: register_settings_get(), register_settings_update(), execute_settings_get(), execute_settings_update(), get_settings_get_input_schema(), get_settings_get_output_schema(), check_permission(), and a CATEGORY constant. - Label the abilities `Get Settings` and `Update Settings`, verb first like the other core abilities, and say in the get description that it requires an authenticated user who can manage options. - Reject duplicate names in the `fields` filter with `uniqueItems`. - Explain in the class docblock why the settings abilities live in a dedicated class instead of closures in wp_register_core_abilities(), as the users and content classes do.
| 'settings_invalid_param', | ||
| /* translators: %s: List of invalid parameters. */ | ||
| sprintf( __( 'Invalid parameter(s): %s', 'ai' ), implode( ', ', $invalid_params ) ), | ||
| array( 'status' => 400 ) |
There was a problem hiding this comment.
Could we include the invalid setting names in the error data? We already collect them in $invalid_params; exposing them would let callers identify what to fix without parsing a translated message.
Only init() and register() stay public. The permission and execute callbacks of `core/settings-get` and `core/settings-update` are now private methods, registered through closures defined in the class, so callers run the abilities through the Abilities API, such as `wp_get_ability( 'core/settings-get' )->execute()`, which validates the input and checks permissions first. The test that calls the update callback directly now captures it from the registration arguments, through the `wp_register_ability_args` filter, so register_ability() no longer returns the instance. Ported from WordPress/wordpress-develop#12141.
- Map each invalid setting to its messages under `params`, and to its error under `details`, in the `settings_invalid_param` error data, as the REST API's `rest_invalid_param` errors do, so callers can tell which setting failed without parsing the translated message. - Pass the setting name to the schema validation, so its messages name the setting.
On WordPress 7.1, `public` also enables REST exposure, and the default MCP adapter only exposes public abilities, so `core/settings-update` stayed hidden there while `core/settings-get` was exposed. Keep `show_in_rest` for WordPress 7.0, which does not read `public`, as the content and user write abilities do. Also type READ_ONLY_OPTIONS as list<string>.
What?
Adds
core/settings-updatenext tocore/settings-get.Why?
Agents can read the settings exposed to abilities but not change them. This lets them update those settings under the same rules as the REST API.
How?
includes/Abilities/Settings/Settings.php, behind the Custom Abilities experiment withcore/settings-get. Neither ability registers when no setting is exposed.core/settings-getreads excepturlandemail(siteurlandadmin_email), which stay read-only for now: a wrong site URL makes wp-admin unreachable, and wp-admin only changes the admin email after the new address confirms it. As in the settings endpoint, only users who can manage privacy options, network admins on multisite, can changepage_for_privacy_policy. For a setting with a registered default (among core settings,language,use_smiliesandposts_per_page),nullresets the setting to that default. Unknown names, empty input andnullfor a setting without a default are rejected; the endpoint deletes such a setting, leaving it without a value.WP_REST_Settings_Controller::update_item(). Every value is sanitized against its schema before any is written; the REST API does this through each setting'ssanitize_callbackarg option, while the Abilities API only validates. Settings are written in registration order, objects reject undeclared properties, andnullis refused withsettings_invalid_stored_valuewhile the stored value fails validation. Unlike the endpoint, which checks stored values while writing and keeps the settings it already wrote, every check runs before any write, so an error leaves every setting unchanged. A value that sanitizing makes invalid is refused withsettings_invalid_param, where the endpoint stores it:%ab@x.coin a setting with theemailformat would be stored as@x.co.nullresets a boolean stored asfalse, which WordPress saves as''; the endpoint refuses that reset. The endpoint'snullonly deletes the stored value, while the ability then stores the registered default: core registers its settings, and so their defaults, only in REST and abilities requests, so after the endpoint's{ "posts_per_page": null }other requests readfalseand show one post per page. For the same reason, a value that matches the registered default is stored when no value is, whereupdate_option()stores nothing. A setting with no stored value reads as its registered default, sonullcan reset it, where the endpoint refuses thatnullwith a 500. The endpoint also skips a privacy policy page change from users who cannot manage privacy options, while the ability refuses the update withsettings_cannot_manage_privacy_options. Error codes usesettings_in place ofrest_, and the REST-only filters do not run.core/settings-getreads them after the update; the endpoint answers with the whole settings object, whichcore/settings-getstill returns.core/settings-getnow sanitizes each stored value against its schema and leaves out a value the schema rejects, before or after sanitizing, instead of failing for every setting; the endpoint answersnullfor such a value. Without that, a setting without a default that the endpoint reset tonull, such asdefault_ping_status, would failcore/settings-getfor every setting. A boolean stored asfalse, which WordPress saves as'', reads asfalse.core/settings-getability wordpress-develop#12141), a setting flagged withshow_in_abilities => truetakes its name and schema fromshow_in_rest, and every core setting is flagged withtrue. Both abilities, and the deprecatedcore/read-settingsalias, now use the settings endpoint's names:title,description,url,email,timezone,languageandpage_for_privacy_policyreplaceblogname,blogdescription,siteurl,admin_email,timezone_string,WPLANGandwp_page_for_privacy_policy.urlgets the endpoint'suriformat, which the abilities client accepts since WordPress 7.1.null.Testing Instructions
core/settings-updatewith{ "title": "New name" }, then with{ "posts_per_page": null }. The first call returns{ "title": "New name" }, the second{ "posts_per_page": 10 }.{ "url": "https://example.com" }and{ "default_ping_status": null }are rejected.npm run test:php -- --filter 'SettingsTest|Gated_AbilitiesTest|Custom_AbilitiesTest'npm run test:e2e -- tests/e2e/specs/abilities/core-settings-update.spec.jsChangelog Entry
AI disclosure: the latest fixes come from an AI-assisted code review of the core port, and were drafted with AI assistance (Claude Code) and reviewed by me.