Changeset 62419
- Timestamp:
- 05/26/2026 08:58:11 AM (3 months ago)
- Location:
- trunk
- Files:
-
- 2 edited
-
src/wp-includes/abilities.php (modified) (1 diff)
-
tests/phpunit/tests/abilities-api/wpRegisterCoreAbilities.php (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/abilities.php
r62396 r62419 135 135 ); 136 136 137 $user_info_properties = array( 138 'id' => array( 139 'type' => 'integer', 140 'title' => __( 'User ID' ), 141 'description' => __( 'Unique numeric identifier for the user.' ), 142 ), 143 'display_name' => array( 144 'type' => 'string', 145 'title' => __( 'Display Name' ), 146 'description' => __( 'Public-facing name selected by the user.' ), 147 ), 148 'user_nicename' => array( 149 'type' => 'string', 150 'title' => __( 'User Nicename' ), 151 'description' => __( 'URL-friendly slug for the user. Defaults to the username.' ), 152 ), 153 'user_login' => array( 154 'type' => 'string', 155 'title' => __( 'Username' ), 156 'description' => __( 'Login identifier for the user. Cannot be changed once set.' ), 157 ), 158 'roles' => array( 159 'type' => 'array', 160 'title' => __( 'Roles' ), 161 'description' => __( 'Roles assigned to the user, such as administrator, editor, author, contributor, or subscriber.' ), 162 'items' => array( 163 'type' => 'string', 164 ), 165 ), 166 'locale' => array( 167 'type' => 'string', 168 'title' => __( 'Language' ), 169 'description' => __( 'Locale code for the user, such as en_US.' ), 170 ), 171 'first_name' => array( 172 'type' => 'string', 173 'title' => __( 'First Name' ), 174 'description' => __( 'Given name.' ), 175 ), 176 'last_name' => array( 177 'type' => 'string', 178 'title' => __( 'Last Name' ), 179 'description' => __( 'Family name.' ), 180 ), 181 'nickname' => array( 182 'type' => 'string', 183 'title' => __( 'Nickname' ), 184 'description' => __( 'Informal name. Defaults to the username.' ), 185 ), 186 'description' => array( 187 'type' => 'string', 188 'title' => __( 'Biographical Info' ), 189 'description' => __( 'User-authored biography, often shown on author pages.' ), 190 ), 191 'user_url' => array( 192 'type' => 'string', 193 'title' => __( 'Website' ), 194 'description' => __( 'Personal website URL.' ), 195 ), 196 ); 197 $user_info_fields = array_keys( $user_info_properties ); 198 137 199 wp_register_ability( 138 200 'core/get-user-info', 139 201 array( 140 202 'label' => __( 'Get User Information' ), 141 'description' => __( 'Returns basic profile details for the current authenticated user to support personalization, auditing, and access-aware behavior.' ),203 'description' => __( 'Returns profile details for the current authenticated user to support personalization, auditing, and access-aware behavior. By default returns all fields, or optionally a filtered subset.' ), 142 204 'category' => $category_user, 143 'output_schema' => array( 144 'type' => 'object', 145 'required' => array( 'id', 'display_name', 'user_nicename', 'user_login', 'roles', 'locale' ), 205 'input_schema' => array( 206 'type' => 'object', 146 207 'properties' => array( 147 'id' => array( 148 'type' => 'integer', 149 'description' => __( 'The user ID.' ), 150 ), 151 'display_name' => array( 152 'type' => 'string', 153 'description' => __( 'The display name of the user.' ), 154 ), 155 'user_nicename' => array( 156 'type' => 'string', 157 'description' => __( 'The URL-friendly name for the user.' ), 158 ), 159 'user_login' => array( 160 'type' => 'string', 161 'description' => __( 'The login username for the user.' ), 162 ), 163 'roles' => array( 208 'fields' => array( 164 209 'type' => 'array', 165 'description' => __( 'The roles assigned to the user.' ),166 210 'items' => array( 167 211 'type' => 'string', 212 'enum' => $user_info_fields, 168 213 ), 169 ), 170 'locale' => array( 171 'type' => 'string', 172 'description' => __( 'The locale string for the user, such as en_US.' ), 173 ), 174 ), 175 'additionalProperties' => false, 176 ), 177 'execute_callback' => static function (): array { 178 $current_user = wp_get_current_user(); 179 180 return array( 214 'description' => __( 'Optional: Limit response to specific fields. If omitted, all fields are returned.' ), 215 ), 216 ), 217 'additionalProperties' => false, 218 'default' => array(), 219 ), 220 'output_schema' => array( 221 'type' => 'object', 222 'properties' => $user_info_properties, 223 'additionalProperties' => false, 224 ), 225 'execute_callback' => static function ( $input = array() ) use ( $user_info_fields ): array { 226 $input = is_array( $input ) ? $input : array(); 227 $requested_fields = ! empty( $input['fields'] ) ? $input['fields'] : $user_info_fields; 228 $current_user = wp_get_current_user(); 229 230 $all = array( 181 231 'id' => $current_user->ID, 182 232 'display_name' => $current_user->display_name, 183 233 'user_nicename' => $current_user->user_nicename, 184 234 'user_login' => $current_user->user_login, 185 'roles' => $current_user->roles, 235 // Ensure roles are encoded as a JSON array, regardless of their array keys. 236 'roles' => array_values( $current_user->roles ), 186 237 'locale' => get_user_locale( $current_user ), 238 'first_name' => $current_user->first_name, 239 'last_name' => $current_user->last_name, 240 'nickname' => $current_user->nickname, 241 'description' => $current_user->description, 242 'user_url' => $current_user->user_url, 187 243 ); 244 245 return array_intersect_key( $all, array_flip( $requested_fields ) ); 188 246 }, 189 247 'permission_callback' => static function (): bool { -
trunk/tests/phpunit/tests/abilities-api/wpRegisterCoreAbilities.php
r62396 r62419 163 163 $user_id = self::factory()->user->create( 164 164 array( 165 'role' => 'subscriber', 166 'locale' => 'fr_FR', 165 'role' => 'subscriber', 166 'locale' => 'fr_FR', 167 'first_name' => 'Jane', 168 'last_name' => 'Doe', 169 'nickname' => 'janed', 170 'description' => 'Site contributor.', 171 'user_url' => 'https://example.com', 167 172 ) 168 173 ); … … 179 184 $this->assertSame( 'subscriber', $result['roles'][0] ); 180 185 $this->assertSame( get_userdata( $user_id )->display_name, $result['display_name'] ); 186 187 // New profile fields should be present by default. 188 $this->assertSame( 'Jane', $result['first_name'] ); 189 $this->assertSame( 'Doe', $result['last_name'] ); 190 $this->assertSame( 'janed', $result['nickname'] ); 191 $this->assertSame( 'Site contributor.', $result['description'] ); 192 $this->assertSame( 'https://example.com', $result['user_url'] ); 193 } 194 195 /** 196 * Tests that the `core/get-user-info` ability is registered with the expected schema. 197 * @ticket 65234 198 */ 199 public function test_core_get_user_info_ability_is_registered(): void { 200 $ability = wp_get_ability( 'core/get-user-info' ); 201 202 $this->assertInstanceOf( WP_Ability::class, $ability ); 203 204 $input_schema = $ability->get_input_schema(); 205 $output_schema = $ability->get_output_schema(); 206 207 // Input schema should expose an optional `fields` array with an enum of valid field names. 208 $this->assertSame( 'object', $input_schema['type'] ); 209 $this->assertArrayHasKey( 'default', $input_schema ); 210 $this->assertSame( array(), $input_schema['default'] ); 211 $this->assertArrayHasKey( 'fields', $input_schema['properties'] ); 212 $this->assertSame( 'array', $input_schema['properties']['fields']['type'] ); 213 214 $enum = $input_schema['properties']['fields']['items']['enum']; 215 foreach ( array( 'id', 'display_name', 'first_name', 'last_name', 'nickname', 'description', 'user_url' ) as $field ) { 216 $this->assertContains( $field, $enum ); 217 } 218 219 // Output schema should document the original and new profile fields with title + description. 220 foreach ( array( 'id', 'display_name', 'first_name', 'last_name', 'nickname', 'description', 'user_url' ) as $field ) { 221 $this->assertArrayHasKey( $field, $output_schema['properties'] ); 222 $this->assertArrayHasKey( 'title', $output_schema['properties'][ $field ] ); 223 $this->assertArrayHasKey( 'description', $output_schema['properties'][ $field ] ); 224 } 225 } 226 227 /** 228 * Tests that the `core/get-user-info` ability filters its output by the `fields` input parameter. 229 * @ticket 65234 230 */ 231 public function test_core_get_user_info_filters_fields(): void { 232 $user_id = self::factory()->user->create( 233 array( 234 'role' => 'subscriber', 235 'first_name' => 'Jane', 236 'last_name' => 'Doe', 237 ) 238 ); 239 wp_set_current_user( $user_id ); 240 241 $ability = wp_get_ability( 'core/get-user-info' ); 242 243 $result = $ability->execute( 244 array( 245 'fields' => array( 'display_name', 'first_name', 'last_name' ), 246 ) 247 ); 248 249 $this->assertIsArray( $result ); 250 $this->assertCount( 3, $result ); 251 $this->assertArrayHasKey( 'display_name', $result ); 252 $this->assertArrayHasKey( 'first_name', $result ); 253 $this->assertArrayHasKey( 'last_name', $result ); 254 $this->assertArrayNotHasKey( 'id', $result ); 255 $this->assertArrayNotHasKey( 'roles', $result ); 256 $this->assertSame( 'Jane', $result['first_name'] ); 257 $this->assertSame( 'Doe', $result['last_name'] ); 258 } 259 260 /** 261 * Tests that the `core/get-user-info` ability rejects unknown field names via schema validation. 262 * @ticket 65234 263 */ 264 public function test_core_get_user_info_rejects_invalid_fields(): void { 265 $user_id = self::factory()->user->create( array( 'role' => 'subscriber' ) ); 266 wp_set_current_user( $user_id ); 267 268 $ability = wp_get_ability( 'core/get-user-info' ); 269 270 $result = $ability->execute( 271 array( 272 'fields' => array( 'display_name', 'not_a_real_field' ), 273 ) 274 ); 275 276 $this->assertWPError( $result ); 277 $this->assertSame( 'ability_invalid_input', $result->get_error_code() ); 181 278 } 182 279
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)