Skip to content

Commit 9f9310d

Browse files
committed
Add new REST API endpoint for Ability Categories
1 parent d3e1cd7 commit 9f9310d

File tree

8 files changed

+829
-4
lines changed

8 files changed

+829
-4
lines changed

src/wp-includes/abilities-api/class-wp-abilities-registry.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Defines WP_Abilities_Registry class.
66
*
77
* @package WordPress
8-
* @subpackage Abilities API
8+
* @subpackage Abilities_API
99
* @since 6.9.0
1010
*/
1111

src/wp-includes/abilities-api/class-wp-ability-categories-registry.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Defines WP_Ability_Categories_Registry class.
66
*
77
* @package WordPress
8-
* @subpackage Abilities API
8+
* @subpackage Abilities_API
99
* @since 6.9.0
1010
*/
1111

src/wp-includes/abilities-api/class-wp-ability-category.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Defines WP_Ability_Category class.
66
*
77
* @package WordPress
8-
* @subpackage Abilities API
8+
* @subpackage Abilities_API
99
* @since 6.9.0
1010
*/
1111

src/wp-includes/abilities-api/class-wp-ability.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Defines WP_Ability class.
66
*
77
* @package WordPress
8-
* @subpackage Abilities API
8+
* @subpackage Abilities_API
99
* @since 6.9.0
1010
*/
1111

src/wp-includes/rest-api.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,8 @@ function create_initial_rest_routes() {
418418
$font_collections_controller->register_routes();
419419

420420
// Abilities.
421+
$abilities_run_controller = new WP_REST_Ability_Categories_Controller();
422+
$abilities_run_controller->register_routes();
421423
$abilities_run_controller = new WP_REST_Abilities_Run_Controller();
422424
$abilities_run_controller->register_routes();
423425
$abilities_list_controller = new WP_REST_Abilities_List_Controller();
Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
<?php
2+
/**
3+
* REST API ability categories controller for Abilities API.
4+
*
5+
* @package WordPress
6+
* @subpackage Abilities_API
7+
* @since 6.9.0
8+
*/
9+
10+
declare( strict_types = 1 );
11+
12+
/**
13+
* Core controller used to access ability categories via the REST API.
14+
*
15+
* @since 6.9.0
16+
*
17+
* @see WP_REST_Controller
18+
*/
19+
class WP_REST_Ability_Categories_Controller extends WP_REST_Controller {
20+
21+
/**
22+
* Default number of items per page for pagination.
23+
*
24+
* @since 6.9.0
25+
* @var int
26+
*/
27+
public const DEFAULT_PER_PAGE = 50;
28+
29+
/**
30+
* REST API namespace.
31+
*
32+
* @since 6.9.0
33+
* @var string
34+
*/
35+
protected $namespace = 'wp/v2';
36+
37+
/**
38+
* REST API base route.
39+
*
40+
* @since 6.9.0
41+
* @var string
42+
*/
43+
protected $rest_base = 'ability-categories';
44+
45+
/**
46+
* Registers the routes for ability categories.
47+
*
48+
* @since 6.9.0
49+
*
50+
* @see register_rest_route()
51+
*/
52+
public function register_routes(): void {
53+
register_rest_route(
54+
$this->namespace,
55+
'/' . $this->rest_base,
56+
array(
57+
array(
58+
'methods' => WP_REST_Server::READABLE,
59+
'callback' => array( $this, 'get_items' ),
60+
'permission_callback' => array( $this, 'get_permissions_check' ),
61+
'args' => $this->get_collection_params(),
62+
),
63+
'schema' => array( $this, 'get_public_item_schema' ),
64+
)
65+
);
66+
67+
register_rest_route(
68+
$this->namespace,
69+
'/' . $this->rest_base . '/(?P<slug>[a-z0-9]+(?:-[a-z0-9]+)*)',
70+
array(
71+
'args' => array(
72+
'slug' => array(
73+
'description' => __( 'Unique identifier for the ability category.' ),
74+
'type' => 'string',
75+
'pattern' => '^[a-z0-9]+(?:-[a-z0-9]+)*$',
76+
),
77+
),
78+
array(
79+
'methods' => WP_REST_Server::READABLE,
80+
'callback' => array( $this, 'get_item' ),
81+
'permission_callback' => array( $this, 'get_permissions_check' ),
82+
),
83+
'schema' => array( $this, 'get_public_item_schema' ),
84+
)
85+
);
86+
}
87+
88+
/**
89+
* Retrieves all ability categories.
90+
*
91+
* @since 6.9.0
92+
*
93+
* @param WP_REST_Request<array<string, mixed>> $request Full details about the request.
94+
* @return WP_REST_Response Response object on success.
95+
*/
96+
public function get_items( $request ) {
97+
$categories = wp_get_ability_categories();
98+
99+
$params = $request->get_params();
100+
$page = $params['page'] ?? 1;
101+
$per_page = $params['per_page'] ?? self::DEFAULT_PER_PAGE;
102+
$offset = ( $page - 1 ) * $per_page;
103+
104+
$total_categories = count( $categories );
105+
$max_pages = ceil( $total_categories / $per_page );
106+
107+
if ( $request->get_method() === 'HEAD' ) {
108+
$response = new WP_REST_Response( array() );
109+
} else {
110+
$categories = array_slice( $categories, $offset, $per_page );
111+
112+
$data = array();
113+
foreach ( $categories as $category ) {
114+
$item = $this->prepare_item_for_response( $category, $request );
115+
$data[] = $this->prepare_response_for_collection( $item );
116+
}
117+
118+
$response = rest_ensure_response( $data );
119+
}
120+
121+
$response->header( 'X-WP-Total', (string) $total_categories );
122+
$response->header( 'X-WP-TotalPages', (string) $max_pages );
123+
124+
$query_params = $request->get_query_params();
125+
$base = add_query_arg(
126+
urlencode_deep( $query_params ),
127+
rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) )
128+
);
129+
130+
if ( $page > 1 ) {
131+
$prev_page = $page - 1;
132+
$prev_link = add_query_arg( 'page', $prev_page, $base );
133+
$response->link_header( 'prev', $prev_link );
134+
}
135+
136+
if ( $page < $max_pages ) {
137+
$next_page = $page + 1;
138+
$next_link = add_query_arg( 'page', $next_page, $base );
139+
$response->link_header( 'next', $next_link );
140+
}
141+
142+
return $response;
143+
}
144+
145+
/**
146+
* Retrieves a specific ability category.
147+
*
148+
* @since 6.9.0
149+
*
150+
* @param WP_REST_Request<array<string, mixed>> $request Full details about the request.
151+
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
152+
*/
153+
public function get_item( $request ) {
154+
$category = wp_get_ability_category( $request->get_param( 'slug' ) );
155+
if ( ! $category ) {
156+
return new WP_Error(
157+
'rest_ability_category_not_found',
158+
__( 'Ability category not found.' ),
159+
array( 'status' => 404 )
160+
);
161+
}
162+
163+
$data = $this->prepare_item_for_response( $category, $request );
164+
return rest_ensure_response( $data );
165+
}
166+
167+
/**
168+
* Checks if a given request has access to read ability categories.
169+
*
170+
* @since 6.9.0
171+
*
172+
* @param WP_REST_Request<array<string, mixed>> $request Full details about the request.
173+
* @return bool True if the request has read access.
174+
*/
175+
public function get_permissions_check( $request ) {
176+
return current_user_can( 'read' );
177+
}
178+
179+
/**
180+
* Prepares an ability category for response.
181+
*
182+
* @since 6.9.0
183+
*
184+
* @param WP_Ability_Category $category The ability category object.
185+
* @param WP_REST_Request<array<string, mixed>> $request Request object.
186+
* @return WP_REST_Response Response object.
187+
*/
188+
public function prepare_item_for_response( $category, $request ) {
189+
$data = array(
190+
'slug' => $category->get_slug(),
191+
'label' => $category->get_label(),
192+
'description' => $category->get_description(),
193+
'meta' => $category->get_meta(),
194+
);
195+
196+
$context = $request->get_param( 'context' ) ?? 'view';
197+
$data = $this->add_additional_fields_to_object( $data, $request );
198+
$data = $this->filter_response_by_context( $data, $context );
199+
200+
$response = rest_ensure_response( $data );
201+
202+
$fields = $this->get_fields_for_response( $request );
203+
if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) {
204+
$links = array(
205+
'self' => array(
206+
'href' => rest_url( sprintf( '%s/%s/%s', $this->namespace, $this->rest_base, $category->get_slug() ) ),
207+
),
208+
'collection' => array(
209+
'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ),
210+
),
211+
'abilities' => array(
212+
'href' => rest_url( sprintf( '%s/abilities?category=%s', $this->namespace, $category->get_slug() ) ),
213+
),
214+
);
215+
216+
$response->add_links( $links );
217+
}
218+
219+
return $response;
220+
}
221+
222+
/**
223+
* Retrieves the ability category's schema, conforming to JSON Schema.
224+
*
225+
* @since 6.9.0
226+
*
227+
* @return array<string, mixed> Item schema data.
228+
*/
229+
public function get_item_schema(): array {
230+
$schema = array(
231+
'$schema' => 'http://json-schema.org/draft-04/schema#',
232+
'title' => 'ability-category',
233+
'type' => 'object',
234+
'properties' => array(
235+
'slug' => array(
236+
'description' => __( 'Unique identifier for the ability category.' ),
237+
'type' => 'string',
238+
'context' => array( 'view', 'edit', 'embed' ),
239+
'readonly' => true,
240+
),
241+
'label' => array(
242+
'description' => __( 'Display label for the category.' ),
243+
'type' => 'string',
244+
'context' => array( 'view', 'edit', 'embed' ),
245+
'readonly' => true,
246+
),
247+
'description' => array(
248+
'description' => __( 'Description of the category.' ),
249+
'type' => 'string',
250+
'context' => array( 'view', 'edit' ),
251+
'readonly' => true,
252+
),
253+
'meta' => array(
254+
'description' => __( 'Meta information about the category.' ),
255+
'type' => 'object',
256+
'context' => array( 'view', 'edit' ),
257+
'readonly' => true,
258+
),
259+
),
260+
'required' => array( 'slug', 'label', 'description', 'meta' ),
261+
);
262+
263+
return $this->add_additional_fields_schema( $schema );
264+
}
265+
266+
/**
267+
* Retrieves the query params for collections.
268+
*
269+
* @since 6.9.0
270+
*
271+
* @return array<string, mixed> Collection parameters.
272+
*/
273+
public function get_collection_params(): array {
274+
return array(
275+
'context' => $this->get_context_param( array( 'default' => 'view' ) ),
276+
'page' => array(
277+
'description' => __( 'Current page of the collection.' ),
278+
'type' => 'integer',
279+
'default' => 1,
280+
'minimum' => 1,
281+
),
282+
'per_page' => array(
283+
'description' => __( 'Maximum number of items to be returned in result set.' ),
284+
'type' => 'integer',
285+
'default' => self::DEFAULT_PER_PAGE,
286+
'minimum' => 1,
287+
'maximum' => 100,
288+
),
289+
);
290+
}
291+
}

src/wp-settings.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@
335335
require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-font-families-controller.php';
336336
require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-font-faces-controller.php';
337337
require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-font-collections-controller.php';
338+
require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-ability-categories-controller.php';
338339
require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-abilities-list-controller.php';
339340
require ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-abilities-run-controller.php';
340341
require ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-meta-fields.php';

0 commit comments

Comments
 (0)