-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
REST API: new endpoint to fetch post counts by post status #66294
Closed
Closed
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
6123cb2
First commit: create a new endpoint to retrieve post counts by status.
ramonjd e3641f4
Linty McGinty
ramonjd faa66bb
Linty McGinty
ramonjd bcf76be
use gmdate instead of date
ramonjd 3895345
Because there can be custom post statuses, use get_post_stati to retu…
ramonjd 71404bd
Allow embed
ramonjd 17ad338
Update annotation.
ramonjd 927ac87
Backport log
ramonjd 36c6871
Update class-gutenberg-rest-post-counts-controller.php
ramonjd e0a5fdc
Update class-gutenberg-rest-post-counts-controller-test.php
ramonjd d4a729b
Update load.php
ramonjd 260f0ac
Merge branch 'trunk' into add/rest-api-posts-counts-controller
ramonjd 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 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,3 @@ | ||
https://github.com/WordPress/wordpress-develop/pull/7773 | ||
|
||
* https://github.com/WordPress/gutenberg/pull/66294 |
190 changes: 190 additions & 0 deletions
190
lib/compat/wordpress-6.8/class-gutenberg-rest-post-counts-controller.php
This file contains 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,190 @@ | ||
<?php | ||
/** | ||
* REST API: Gutenberg_REST_Post_Counts_Controller class | ||
* | ||
* @since 6.8.0 | ||
* | ||
* @package gutenberg | ||
* @subpackage REST_API | ||
*/ | ||
|
||
/** | ||
* Core class used to return post counts by post type via the REST API. | ||
* | ||
* @since 6.8.0 | ||
* | ||
* @see WP_REST_Controller | ||
*/ | ||
class Gutenberg_REST_Post_Counts_Controller extends WP_REST_Controller { | ||
|
||
/** | ||
* Constructor. | ||
*/ | ||
public function __construct() { | ||
$this->namespace = 'wp/v2'; | ||
$this->rest_base = 'counts'; | ||
} | ||
|
||
/** | ||
* Registers the routes for post counts. | ||
* | ||
* @since 6.8.0 | ||
* | ||
* @see register_rest_route() | ||
*/ | ||
public function register_routes() { | ||
register_rest_route( | ||
$this->namespace, | ||
'/' . $this->rest_base . '/(?P<post_type>[\w-]+)', | ||
array( | ||
'args' => array( | ||
'post_type' => array( | ||
'description' => __( 'An alphanumeric identifier for the post type.' ), | ||
'type' => 'string', | ||
), | ||
), | ||
array( | ||
'methods' => WP_REST_Server::READABLE, | ||
'callback' => array( $this, 'get_item' ), | ||
'permission_callback' => array( $this, 'get_item_permissions_check' ), | ||
'args' => array( | ||
'context' => $this->get_context_param( array( 'default' => 'view' ) ), | ||
), | ||
), | ||
'schema' => array( $this, 'get_public_item_schema' ), | ||
) | ||
); | ||
} | ||
|
||
/** | ||
* Checks if a given request has access to read post counts. | ||
* | ||
* @since 6.8.0 | ||
* | ||
* @param WP_REST_Request $request Full details about the request. | ||
* @return true|WP_Error True if the request has read access, WP_Error object otherwise. | ||
*/ | ||
public function get_item_permissions_check( $request ) { | ||
$post_type = get_post_type_object( $request['post_type'] ); | ||
|
||
if ( empty( $post_type ) ) { | ||
return new WP_Error( | ||
'rest_invalid_post_type', | ||
__( 'Invalid post type.' ), | ||
array( 'status' => 404 ) | ||
); | ||
} | ||
|
||
if ( ! current_user_can( $post_type->cap->read ) ) { | ||
return new WP_Error( | ||
'rest_cannot_read', | ||
__( 'Sorry, you are not allowed to read post counts for this post type.' ), | ||
array( 'status' => rest_authorization_required_code() ) | ||
); | ||
} | ||
|
||
return true; | ||
} | ||
|
||
/** | ||
* Retrieves post counts for a specific post type. | ||
* | ||
* @since 6.8.0 | ||
* | ||
* @param WP_REST_Request $request Full details about the request. | ||
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. | ||
*/ | ||
public function get_item( $request ) { | ||
$post_type = $request['post_type']; | ||
$counts = wp_count_posts( $post_type ); | ||
$data = $this->prepare_item_for_response( $counts, $request ); | ||
|
||
return rest_ensure_response( $data ); | ||
} | ||
|
||
/** | ||
* Prepares post counts for response. | ||
* | ||
* @since 6.8.0 | ||
* | ||
* @param object $item Post counts data. | ||
* @param WP_REST_Request $request Request object. | ||
* @return WP_REST_Response Response object. | ||
*/ | ||
public function prepare_item_for_response( $item, $request ) { | ||
$data = array(); | ||
|
||
if ( ! empty( $item ) ) { | ||
/* | ||
* The fields comprise all non-internal post statuses, | ||
* including any custom statuses that may be registered. | ||
* 'trash' is an exception, so if it exists, it is added separately. | ||
*/ | ||
$post_stati = get_post_stati( array( 'internal' => false ) ); | ||
|
||
if ( get_post_status_object( 'trash' ) ) { | ||
$post_stati[] = 'trash'; | ||
} | ||
// Include all public statuses in the response if there is a count. | ||
foreach ( $post_stati as $status ) { | ||
if ( isset( $item->$status ) ) { | ||
$data[ $status ] = (int) $item->$status; | ||
} | ||
} | ||
} | ||
|
||
$context = ! empty( $request['context'] ) ? $request['context'] : 'view'; | ||
$data = $this->add_additional_fields_to_object( $data, $request ); | ||
$data = $this->filter_response_by_context( $data, $context ); | ||
|
||
return rest_ensure_response( $data ); | ||
} | ||
|
||
/** | ||
* Retrieves the post counts schema, conforming to JSON Schema. | ||
* | ||
* @since 6.8.0 | ||
* | ||
* @return array Item schema data. | ||
*/ | ||
public function get_item_schema() { | ||
if ( $this->schema ) { | ||
return $this->add_additional_fields_schema( $this->schema ); | ||
} | ||
|
||
/* | ||
* The fields comprise all non-internal post stati, | ||
* including any custom statuses that may be registered. | ||
* 'trash' is an exception, so if it exists, it is added separately. | ||
* The caveat is that all custom post statuses | ||
* must be registered at the highest priority, otherwise | ||
* the endpoint will not return them. | ||
*/ | ||
$post_statuses = get_post_stati( array( 'internal' => false ) ); | ||
|
||
if ( get_post_status_object( 'trash' ) ) { | ||
$post_statuses[] = 'trash'; | ||
} | ||
$schema_properties = array(); | ||
foreach ( $post_statuses as $post_status ) { | ||
$schema_properties[ $post_status ] = array( | ||
// translators: %s: Post status. | ||
'description' => sprintf( __( 'The number of posts with the status %s.' ), $post_status ), | ||
'type' => 'integer', | ||
'context' => array( 'view', 'edit' ), | ||
'readonly' => true, | ||
); | ||
} | ||
|
||
$schema = array( | ||
ramonjd marked this conversation as resolved.
Show resolved
Hide resolved
|
||
'$schema' => 'http://json-schema.org/draft-04/schema#', | ||
'title' => 'post-counts', | ||
'type' => 'object', | ||
'properties' => $schema_properties, | ||
); | ||
|
||
$this->schema = $schema; | ||
|
||
return $this->add_additional_fields_schema( $this->schema ); | ||
} | ||
} |
This file contains 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
This file contains 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
Oops, something went wrong.
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.
Hmm, I'm not sure that I love an endpoint specific for post counting. I am not against potentially adding this capability, but I think it feels more natural to be available under the
wp/v2/<post_type>/count
endpoint.I am not sure if there's a technical reason why that would be difficult. But wondering if that could support retrieving the overall count for a specific post type (no arguments) OR with any other passed specific query arguments since they should already be supported within that post type's controller.
@TimothyBJacobs Do you have any opinion on any of these approaches?
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.
Thanks @desrosj This is exactly the feedback I was after 🙇🏻
@Mamaduka also hinted in that direction above
In principle, I don't see any barriers. In fact, that's what I started with locally at least.
I arrived here because the templates controller doesn't inherit the posts controller, and I didn't want to duplicate things, but rather, make the response embeddable.
However, if the consensus is that it'd be better for users to have a route on post-type endpoints, e.g.,
wp/v2/<post_type>/count
, then I'm happy to switch things around.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.
I've thrown up an alternative that adds a
/count
route toWP_REST_Posts_Controller
, sowp/v2/<post_type>/count
as @desrosj mentions above.I'm feeling more comfortable with that version 😄
For Gutenberg, it's only needed for the
page
post type, but in the Core sync it'd be available for all post types that inherit from the controller.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.
I withdraw that position for the reasons stated in:
#66294 (comment)