-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Add: WordPress Core get settings ability #10747
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jorgefilipecosta
wants to merge
5
commits into
WordPress:trunk
Choose a base branch
from
jorgefilipecosta:add/get-settings-ability
base: trunk
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+303
−0
Open
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
86b2521
Initial implementation
jorgefilipecosta 16f89cb
Improve input schema
jorgefilipecosta 8f72312
Improve output schema
jorgefilipecosta 31ccd50
remove irrelevant comments
jorgefilipecosta aeea425
description update
jorgefilipecosta File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
299 changes: 299 additions & 0 deletions
299
src/wp-includes/abilities/class-wp-settings-abilities.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,299 @@ | ||
| <?php | ||
| /** | ||
| * Registers core settings abilities. | ||
| * | ||
| * This is a utility class to encapsulate the registration of settings-related abilities. | ||
| * It is not intended to be instantiated or consumed directly by any other code or plugin. | ||
| * | ||
| * @package WordPress | ||
| * @subpackage Abilities_API | ||
| * @since 6.9.0 | ||
| * | ||
| * @internal This class is not part of the public API. | ||
| * @access private | ||
| */ | ||
|
|
||
| declare( strict_types=1 ); | ||
|
|
||
| /** | ||
| * Registers core settings abilities. | ||
| * | ||
| * @since 6.9.0 | ||
| * @access private | ||
| */ | ||
| class WP_Settings_Abilities { | ||
|
|
||
| /** | ||
| * Available setting groups with show_in_rest enabled. | ||
| * | ||
| * @since 6.9.0 | ||
| * @var array | ||
| */ | ||
| private static $available_groups; | ||
|
|
||
| /** | ||
| * Dynamic output schema built from registered settings. | ||
| * | ||
| * @since 6.9.0 | ||
| * @var array | ||
| */ | ||
| private static $output_schema; | ||
|
|
||
| /** | ||
| * Registers all settings abilities. | ||
| * | ||
| * @since 6.9.0 | ||
| * | ||
| * @return void | ||
| */ | ||
| public static function register(): void { | ||
| self::init(); | ||
| self::register_get_settings(); | ||
| } | ||
|
|
||
| /** | ||
| * Initializes shared data for settings abilities. | ||
| * | ||
| * @since 6.9.0 | ||
| * | ||
| * @return void | ||
| */ | ||
| private static function init(): void { | ||
| self::$available_groups = self::get_available_groups(); | ||
| self::$output_schema = self::build_output_schema(); | ||
| } | ||
|
|
||
| /** | ||
| * Gets unique setting groups that have show_in_rest enabled. | ||
| * | ||
| * @since 6.9.0 | ||
| * | ||
| * @return array List of unique group names. | ||
| */ | ||
| private static function get_available_groups(): array { | ||
| $groups = array(); | ||
|
|
||
| foreach ( get_registered_settings() as $args ) { | ||
| if ( empty( $args['show_in_rest'] ) ) { | ||
| continue; | ||
| } | ||
|
|
||
| $group = $args['group'] ?? 'general'; | ||
| if ( ! in_array( $group, $groups, true ) ) { | ||
| $groups[] = $group; | ||
| } | ||
| } | ||
|
|
||
| sort( $groups ); | ||
|
|
||
| return $groups; | ||
| } | ||
|
|
||
| /** | ||
| * Builds a rich output schema from registered settings metadata. | ||
| * | ||
| * Creates a JSON Schema that documents each setting group and its settings | ||
| * with their types, titles, descriptions, defaults, and any additional | ||
| * schema properties from show_in_rest. | ||
| * | ||
| * @since 6.9.0 | ||
| * | ||
| * @return array JSON Schema for the output. | ||
| */ | ||
| private static function build_output_schema(): array { | ||
| $group_properties = array(); | ||
|
|
||
| foreach ( get_registered_settings() as $option_name => $args ) { | ||
| if ( empty( $args['show_in_rest'] ) ) { | ||
| continue; | ||
| } | ||
|
|
||
| $group = $args['group'] ?? 'general'; | ||
|
|
||
| $rest_name = $option_name; | ||
| if ( is_array( $args['show_in_rest'] ) && ! empty( $args['show_in_rest']['name'] ) ) { | ||
| $rest_name = $args['show_in_rest']['name']; | ||
| } | ||
|
|
||
| $setting_schema = array( | ||
| 'type' => $args['type'] ?? 'string', | ||
| ); | ||
|
|
||
| if ( ! empty( $args['label'] ) ) { | ||
| $setting_schema['title'] = $args['label']; | ||
| } | ||
|
|
||
| if ( ! empty( $args['description'] ) ) { | ||
| $setting_schema['description'] = $args['description']; | ||
| } elseif ( ! empty( $args['label'] ) ) { | ||
| $setting_schema['description'] = $args['label']; | ||
| } | ||
|
|
||
| if ( isset( $args['default'] ) ) { | ||
| $setting_schema['default'] = $args['default']; | ||
| } | ||
|
|
||
| if ( is_array( $args['show_in_rest'] ) && ! empty( $args['show_in_rest']['schema'] ) ) { | ||
| $setting_schema = array_merge( $setting_schema, $args['show_in_rest']['schema'] ); | ||
| } | ||
|
|
||
| if ( ! isset( $group_properties[ $group ] ) ) { | ||
| $group_properties[ $group ] = array( | ||
| 'type' => 'object', | ||
| 'description' => sprintf( | ||
| /* translators: %s: Settings group name. */ | ||
| __( '%s settings.' ), | ||
| ucfirst( $group ) | ||
| ), | ||
| 'properties' => array(), | ||
| ); | ||
| } | ||
|
|
||
| $group_properties[ $group ]['properties'][ $rest_name ] = $setting_schema; | ||
| } | ||
|
|
||
| ksort( $group_properties ); | ||
|
|
||
| return array( | ||
| 'type' => 'object', | ||
| 'description' => __( 'Settings grouped by registration group. Each group contains settings with their current values.' ), | ||
| 'properties' => $group_properties, | ||
| ); | ||
| } | ||
|
|
||
| /** | ||
| * Registers the core/get-settings ability. | ||
| * | ||
| * @since 6.9.0 | ||
| * | ||
| * @return void | ||
| */ | ||
| private static function register_get_settings(): void { | ||
| wp_register_ability( | ||
| 'core/get-settings', | ||
| array( | ||
| 'label' => __( 'Get Settings' ), | ||
| 'description' => __( 'Returns registered WordPress settings grouped by their registration group. Returns key-value pairs per setting.' ), | ||
| 'category' => 'site', | ||
| 'input_schema' => array( | ||
| 'type' => 'object', | ||
| 'properties' => array( | ||
| 'group' => array( | ||
| 'type' => 'string', | ||
| 'description' => __( 'Filter settings by group name. If omitted, returns all groups.' ), | ||
| 'enum' => self::$available_groups, | ||
| ), | ||
| ), | ||
| 'additionalProperties' => false, | ||
| 'default' => array(), | ||
| ), | ||
| 'output_schema' => self::$output_schema, | ||
| 'execute_callback' => array( __CLASS__, 'execute_get_settings' ), | ||
| 'permission_callback' => array( __CLASS__, 'check_manage_options' ), | ||
| 'meta' => array( | ||
| 'annotations' => array( | ||
| 'readOnlyHint' => true, | ||
| 'destructiveHint' => false, | ||
| 'idempotentHint' => true, | ||
| ), | ||
| 'show_in_rest' => true, | ||
| ), | ||
| ) | ||
| ); | ||
| } | ||
|
|
||
| /** | ||
| * Permission callback for settings abilities. | ||
| * | ||
| * @since 6.9.0 | ||
| * | ||
| * @return bool True if the current user can manage options, false otherwise. | ||
| */ | ||
| public static function check_manage_options(): bool { | ||
| return current_user_can( 'manage_options' ); | ||
| } | ||
|
|
||
| /** | ||
| * Execute callback for core/get-settings ability. | ||
| * | ||
| * Retrieves all registered settings that are exposed to the REST API, | ||
| * grouped by their registration group. | ||
| * | ||
| * @since 6.9.0 | ||
| * | ||
| * @param array $input { | ||
| * Optional. Input parameters. | ||
| * | ||
| * @type string $group Optional. Filter settings by group name. | ||
| * } | ||
| * @return array Settings grouped by registration group. | ||
| */ | ||
| public static function execute_get_settings( $input = array() ): array { | ||
| $input = is_array( $input ) ? $input : array(); | ||
| $filter_group = ! empty( $input['group'] ) ? $input['group'] : null; | ||
|
|
||
| $registered_settings = get_registered_settings(); | ||
| $settings_by_group = array(); | ||
|
|
||
| foreach ( $registered_settings as $option_name => $args ) { | ||
| if ( empty( $args['show_in_rest'] ) ) { | ||
| continue; | ||
| } | ||
|
|
||
| $group = $args['group'] ?? 'general'; | ||
|
|
||
| if ( $filter_group && $group !== $filter_group ) { | ||
| continue; | ||
| } | ||
|
|
||
| $rest_name = $option_name; | ||
| if ( is_array( $args['show_in_rest'] ) && ! empty( $args['show_in_rest']['name'] ) ) { | ||
| $rest_name = $args['show_in_rest']['name']; | ||
| } | ||
|
|
||
| $default = $args['default'] ?? null; | ||
| if ( is_array( $args['show_in_rest'] ) && isset( $args['show_in_rest']['schema']['default'] ) ) { | ||
| $default = $args['show_in_rest']['schema']['default']; | ||
| } | ||
|
|
||
| $value = get_option( $option_name, $default ); | ||
| $value = self::cast_value( $value, $args['type'] ?? 'string' ); | ||
|
|
||
| if ( ! isset( $settings_by_group[ $group ] ) ) { | ||
| $settings_by_group[ $group ] = array(); | ||
| } | ||
|
|
||
| $settings_by_group[ $group ][ $rest_name ] = $value; | ||
| } | ||
|
|
||
| ksort( $settings_by_group ); | ||
|
|
||
| return $settings_by_group; | ||
| } | ||
|
|
||
| /** | ||
| * Casts a value to the appropriate type based on the setting's registered type. | ||
| * | ||
| * @since 6.9.0 | ||
| * | ||
| * @param mixed $value The value to cast. | ||
| * @param string $type The registered type (string, boolean, integer, number, array, object). | ||
| * @return mixed The cast value. | ||
| */ | ||
| private static function cast_value( $value, string $type ) { | ||
| switch ( $type ) { | ||
| case 'boolean': | ||
| return (bool) $value; | ||
| case 'integer': | ||
| return (int) $value; | ||
| case 'number': | ||
| return (float) $value; | ||
| case 'array': | ||
| case 'object': | ||
| return is_array( $value ) ? $value : array(); | ||
| case 'string': | ||
| default: | ||
| return (string) $value; | ||
| } | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be
7.0.0