1<?php
2/**
3 * Core Abilities registration.
4 *
5 * @package WordPress
6 * @subpackage Abilities_API
7 * @since 6.9.0
8 */
9
10declare( strict_types = 1 );
11
12/**
13 * Registers the core ability categories.
14 *
15 * @since 6.9.0
16 *
17 * @return void
18 */
19function wp_register_core_ability_categories(): void {
20 wp_register_ability_category(
21 'site',
22 array(
23 'label' => __( 'Site' ),
24 'description' => __( 'Abilities that retrieve or modify site information and settings.' ),
25 )
26 );
27
28 wp_register_ability_category(
29 'user',
30 array(
31 'label' => __( 'User' ),
32 'description' => __( 'Abilities that retrieve or modify user information and settings.' ),
33 )
34 );
35}
36
37/**
38 * Registers the default core abilities.
39 *
40 * @since 6.9.0
41 *
42 * @return void
43 */
44function wp_register_core_abilities(): void {
45 $category_site = 'site';
46 $category_user = 'user';
47
48 $site_info_properties = array(
49 'name' => array(
50 'type' => 'string',
51 'description' => __( 'The site title.' ),
52 ),
53 'description' => array(
54 'type' => 'string',
55 'description' => __( 'The site tagline.' ),
56 ),
57 'url' => array(
58 'type' => 'string',
59 'description' => __( 'The site home URL.' ),
60 ),
61 'wpurl' => array(
62 'type' => 'string',
63 'description' => __( 'The WordPress installation URL.' ),
64 ),
65 'admin_email' => array(
66 'type' => 'string',
67 'description' => __( 'The site administrator email address.' ),
68 ),
69 'charset' => array(
70 'type' => 'string',
71 'description' => __( 'The site character encoding.' ),
72 ),
73 'language' => array(
74 'type' => 'string',
75 'description' => __( 'The site language locale code.' ),
76 ),
77 'version' => array(
78 'type' => 'string',
79 'description' => __( 'The WordPress version.' ),
80 ),
81 );
82 $site_info_fields = array_keys( $site_info_properties );
83
84 wp_register_ability(
85 'core/get-site-info',
86 array(
87 'label' => __( 'Get Site Information' ),
88 'description' => __( 'Returns site information configured in WordPress. By default returns all fields, or optionally a filtered subset.' ),
89 'category' => $category_site,
90 'input_schema' => array(
91 'type' => 'object',
92 'properties' => array(
93 'fields' => array(
94 'type' => 'array',
95 'items' => array(
96 'type' => 'string',
97 'enum' => $site_info_fields,
98 ),
99 'description' => __( 'Optional: Limit response to specific fields. If omitted, all fields are returned.' ),
100 ),
101 ),
102 'additionalProperties' => false,
103 'default' => array(),
104 ),
105 'output_schema' => array(
106 'type' => 'object',
107 'properties' => $site_info_properties,
108 'additionalProperties' => false,
109 ),
110 'execute_callback' => static function ( $input = array() ) use ( $site_info_fields ): array {
111 $input = is_array( $input ) ? $input : array();
112 $requested_fields = ! empty( $input['fields'] ) ? $input['fields'] : $site_info_fields;
113
114 $result = array();
115 foreach ( $requested_fields as $field ) {
116 $result[ $field ] = get_bloginfo( $field );
117 }
118
119 return $result;
120 },
121 'permission_callback' => static function (): bool {
122 return current_user_can( 'manage_options' );
123 },
124 'meta' => array(
125 'annotations' => array(
126 'readonly' => true,
127 'destructive' => false,
128 'idempotent' => true,
129 ),
130 'show_in_rest' => true,
131 ),
132 )
133 );
134
135 wp_register_ability(
136 'core/get-user-info',
137 array(
138 'label' => __( 'Get User Information' ),
139 'description' => __( 'Returns basic profile details for the current authenticated user to support personalization, auditing, and access-aware behavior.' ),
140 'category' => $category_user,
141 'output_schema' => array(
142 'type' => 'object',
143 'required' => array( 'id', 'display_name', 'user_nicename', 'user_login', 'roles', 'locale' ),
144 'properties' => array(
145 'id' => array(
146 'type' => 'integer',
147 'description' => __( 'The user ID.' ),
148 ),
149 'display_name' => array(
150 'type' => 'string',
151 'description' => __( 'The display name of the user.' ),
152 ),
153 'user_nicename' => array(
154 'type' => 'string',
155 'description' => __( 'The URL-friendly name for the user.' ),
156 ),
157 'user_login' => array(
158 'type' => 'string',
159 'description' => __( 'The login username for the user.' ),
160 ),
161 'roles' => array(
162 'type' => 'array',
163 'description' => __( 'The roles assigned to the user.' ),
164 'items' => array(
165 'type' => 'string',
166 ),
167 ),
168 'locale' => array(
169 'type' => 'string',
170 'description' => __( 'The locale string for the user, such as en_US.' ),
171 ),
172 ),
173 'additionalProperties' => false,
174 ),
175 'execute_callback' => static function (): array {
176 $current_user = wp_get_current_user();
177
178 return array(
179 'id' => $current_user->ID,
180 'display_name' => $current_user->display_name,
181 'user_nicename' => $current_user->user_nicename,
182 'user_login' => $current_user->user_login,
183 'roles' => $current_user->roles,
184 'locale' => get_user_locale( $current_user ),
185 );
186 },
187 'permission_callback' => static function (): bool {
188 return is_user_logged_in();
189 },
190 'meta' => array(
191 'annotations' => array(
192 'readonly' => true,
193 'destructive' => false,
194 'idempotent' => true,
195 ),
196 'show_in_rest' => false,
197 ),
198 )
199 );
200
201 wp_register_ability(
202 'core/get-environment-info',
203 array(
204 'label' => __( 'Get Environment Info' ),
205 'description' => __( 'Returns core details about the site\'s runtime context for diagnostics and compatibility (environment, PHP runtime, database server info, WordPress version).' ),
206 'category' => $category_site,
207 'output_schema' => array(
208 'type' => 'object',
209 'required' => array( 'environment', 'php_version', 'db_server_info', 'wp_version' ),
210 'properties' => array(
211 'environment' => array(
212 'type' => 'string',
213 'description' => __( 'The site\'s runtime environment classification (can be one of these: production, staging, development, local).' ),
214 'enum' => array( 'production', 'staging', 'development', 'local' ),
215 ),
216 'php_version' => array(
217 'type' => 'string',
218 'description' => __( 'The PHP runtime version executing WordPress.' ),
219 ),
220 'db_server_info' => array(
221 'type' => 'string',
222 'description' => __( 'The database server vendor and version string reported by the driver.' ),
223 ),
224 'wp_version' => array(
225 'type' => 'string',
226 'description' => __( 'The WordPress core version running on this site.' ),
227 ),
228 ),
229 'additionalProperties' => false,
230 ),
231 'execute_callback' => static function (): array {
232 global $wpdb;
233
234 $env = wp_get_environment_type();
235 $php_version = phpversion();
236 $db_server_info = '';
237 if ( method_exists( $wpdb, 'db_server_info' ) ) {
238 $db_server_info = $wpdb->db_server_info() ?? '';
239 }
240 $wp_version = get_bloginfo( 'version' );
241
242 return array(
243 'environment' => $env,
244 'php_version' => $php_version,
245 'db_server_info' => $db_server_info,
246 'wp_version' => $wp_version,
247 );
248 },
249 'permission_callback' => static function (): bool {
250 return current_user_can( 'manage_options' );
251 },
252 'meta' => array(
253 'annotations' => array(
254 'readonly' => true,
255 'destructive' => false,
256 'idempotent' => true,
257 ),
258 'show_in_rest' => true,
259 ),
260 )
261 );
262}
263