Make WordPress Core

Opened 4 weeks ago

Last modified 46 hours ago

#64605 reopened enhancement

Add: WordPress Core get settings ability

Reported by: jorgefilipecosta's profile jorgefilipecosta Owned by: jorgefilipecosta's profile jorgefilipecosta
Milestone: Future Release Priority: normal
Severity: normal Version:
Component: AI Keywords: has-patch has-unit-tests
Focuses: Cc:

Description

This ticket tracks the addition of a core/get-settings ability to the WordPress Abilities API. This ability should dynamically discover and exposes all WordPress settings. Abilities that are registered with show_in_abilities = true are exposed.

Change History (11)

This ticket was mentioned in PR #10747 on WordPress/wordpress-develop by @jorgefilipecosta.


3 weeks ago
#1

  • Keywords has-patch has-unit-tests added

Part of: https://github.com/WordPress/ai/issues/40
Inspired by the work on https://github.com/galatanovidiu/mcp-adapter-implementation-example/tree/experiment/layerd-mcp-tools/includes/Abilities by @galatanovidiu.
Ticket: https://core.trac.wordpress.org/ticket/64605
## Summary

This PR adds a core/get-settings ability to the WordPress Abilities API. This ability dynamically discovers and exposes all WordPress settings. For now all abilities that are register show_in_rest = true are exposed. We should probably have a setting related to the ability exposition but can be a follow.

## Organization

Following the pattern established in https://github.com/WordPress/wordpress-develop/pull/10665, this PR adds a new class WP_Settings_Abilities in src/wp-includes/abilities/class-wp-settings-abilities.php. The class is organized into:

  • Initialization: init() method that collects available groups and builds the output schema
  • Schema Building: build_output_schema() creates a rich JSON Schema from registered settings metadata
  • Ability Registration: register_get_settings() registers the ability with dynamic schemas
  • Execution: execute_get_settings() retrieves and returns settings grouped by their registration group
  • Utilities: Helper methods for permission checking and value type casting

## Test plan

  • Open http://localhost:6888/site-wp-dev-1/wp-admin/post-new.php
  • Open the browser console and run the following examples:
// Get all settings
await wp.apiFetch({
  path: wp.url.addQueryArgs(
    '/wp-abilities/v1/abilities/core/get-settings/run'
  )
});
  • [ ] Verify all settings are returned grouped by their registration group (general, reading, writing, discussion)
// Get only general settings
await wp.apiFetch({
  path: wp.url.addQueryArgs(
    '/wp-abilities/v1/abilities/core/get-settings/run',
   { input: { group: 'general' } } 
)});
  • [ ] Verify only general settings are returned when filtering by group
// Check the ability schema
await wp.apiFetch({
  path: '/wp-abilities/v1/abilities/core/get-settings'
});
  • [ ] Verify the input schema includes a dynamic enum of available groups
  • [ ] Verify the output schema documents each group and its settings with types, descriptions, and defaults
  • [ ] Test permission check: Verify non-admin users cannot access the ability (requires manage_options capability)

#2 @jorgefilipecosta
3 weeks ago

  • Owner set to jorgefilipecosta
  • Resolution set to fixed
  • Status changed from new to closed

In 61600:

Abilities API: Add core/get-settings ability.

Introduce a new core/get-settings ability to the WordPress Abilities API that dynamically discovers and exposes WordPress settings. Settings with show_in_abilities enabled are exposed through this ability.

Props jorgefilipecosta, jason_the_adams, mukeshpanchal27, justlevine, ovidiu-galatan.
Fixes #64605.

This ticket was mentioned in PR #10892 on WordPress/wordpress-develop by @jorgefilipecosta.


3 weeks ago
#4

Part of: https://github.com/WordPress/ai/issues/40
Inspired by the work on https://github.com/galatanovidiu/mcp-adapter-implementation-example/tree/experiment/layerd-mcp-tools/includes/Abilities by @galatanovidiu.
Ticket: https://core.trac.wordpress.org/ticket/64605

This PR adds a core/update-settings ability to the WordPress Abilities API. This ability allows updating WordPress settings that have show_in_abilities = true. It complements the existing core/get-settings ability by providing a symmetric API for reading and writing settings.

The input and output structures are designed for symmetry with core/get-settings:

  • Input accepts settings grouped by registration group (same structure returned by core/get-settings)
  • Output returns updated_settings (with updated values) and validation_errors (with error messages) in the same grouped structure

## Organization

Following the pattern established in #10747, this PR extends the WP_Settings_Abilities class in src/wp-includes/abilities/class-wp-settings-abilities.php. The implementation maximizes code reuse:

  • Schema Reuse: Uses a permissive input schema that allows the execute callback to handle validation
  • Shared Methods: Reuses get_allowed_settings(), check_manage_options(), and cast_value() from the existing implementation
  • Registration: register_update_settings() registers the ability with appropriate annotations (readonly: false, destructive: false, idempotent: true)
  • Execution: execute_update_settings() validates, sanitizes, and updates settings, returning both successful updates and validation errors

## Test plan

  • Open /wp-admin/post-new.php
  • Open the browser console and run the following examples:
// Update a single setting
await wp.apiFetch({
  path: '/wp-abilities/v1/abilities/core/update-settings/run',
  method: 'POST',
  data: {
    input: {
      settings: {
        general: {
          blogname: 'New Site Title'
        }
      }
    }
  }
});
  • [ ] Verify the setting is updated in the database
// Update multiple settings across groups
await wp.apiFetch({
  path: '/wp-abilities/v1/abilities/core/update-settings/run',
  method: 'POST',
  data: {
    input: {
      settings: {
        general: {
          blogname: 'New Site Title',
          blogdescription: 'New Tagline'
        },
        reading: {
          posts_per_page: 15
        }
      }
    }
  }
});
  • [ ] Verify multiple settings across different groups are updated
// Check the ability schema
await wp.apiFetch({
  path: '/wp-abilities/v1/abilities/core/update-settings'
});
  • [ ] Verify the input schema documents the settings structure
  • [ ] Verify the output schema documents updated_settings and validation_errors
// Workflow: Get settings, modify, update (symmetry test)
const settings = await wp.apiFetch({
  path: '/wp-abilities/v1/abilities/core/get-settings/run'
});
settings.general.blogname = 'Modified Title';
await wp.apiFetch({
  path: '/wp-abilities/v1/abilities/core/update-settings/run',
  method: 'POST',
  data: { input: { settings } }
});
  • [ ] Verify the get -> modify -> update workflow works seamlessly
// Test partial success with invalid settings
await wp.apiFetch({
  path: '/wp-abilities/v1/abilities/core/update-settings/run',
  method: 'POST',
  data: {
    input: {
      settings: {
        general: {
          blogname: 'Valid Title',
          unknown_setting: 'should fail'
        }
      }
    }
  }
});
  • [ ] Verify blogname is in updated_settings and unknown_setting is in validation_errors
  • [ ] Test permission check: Verify non-admin users cannot access the ability (requires manage_options capability)
  • [ ] Verify settings without show_in_abilities cannot be modified
  • [ ] Verify settings placed in wrong groups are rejected with appropriate error messages

@jorgefilipecosta commented on PR #10892:


3 weeks ago
#5

Thank you @westonruter for reviewing this PR, all your suggestions were applied.

#6 @justlevine
3 weeks ago

I'm surprised this was merged without #64596 or https://github.com/WordPress/wordpress-develop/pull/10892.

If we can't get #64596 resolved in time (in either direction), I would suggest reverting this. As @jorbin noted on that ticket we want to make sure the API is in good shape instead of something that has a strong chance we're going to deprecate.

@justlevine commented on PR #10892:


3 weeks ago
#7

Related to https://core.trac.wordpress.org/ticket/64605, but since that got merged I'll ask here. How exactly does show_in_abilities work here?

Is show_in_abilities: bool|array{schema:array<string,mixed}, or are we in an awkward place where show_in_abilities is a bool, but we're going to infer any schemas from show_in_rest['schema'] ? I'm also not seeing anywhere in this or that PR where's we're loading/coercing the existing schema, am I missing it or was it left out for some reason?

#8 @johnbillion
2 weeks ago

  • Milestone changed from Awaiting Review to 7.0
  • Type changed from defect (bug) to enhancement
  • Version trunk deleted

#9 @desrosj
7 days ago

  • Resolution fixed deleted
  • Status changed from closed to reopened

It looks like [61690] reverted [61600], which auto-closed this ticket as fixed.

I'm not clear if the intention is to work on a new implementation of core/get-settings this as a part of #64455 going forward or not, so I'm reopening.

If this was intentionally left as closed, then the resolution needs to be changed appropriately given the revert.

#10 @justlevine
2 days ago

I'm not clear if the intention is to work on a new implementation of core/get-settings this as a part of #64455 going forward or not, so I'm reopening.

Not sure either (I'd prefer 1 ticket per ability grouping), but either way it's been bumped from 7.0, so someone with perms, please feel free to update the milestone to 7.1

Last edited 2 days ago by justlevine (previous) (diff)

#11 @desrosj
46 hours ago

  • Milestone changed from 7.0 to Future Release

Changing milestone to match #64455.

Note: See TracTickets for help on using tickets.