PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3
Jetpack – WP Security, Backup, Speed, & Growth v16.3
16.3 16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 All 508 releases
← All changes | json-endpoints/class.wpcom-json-api-get-post-counts-v1-1-endpoint.php +176 -0 16.2-beta → 16.3 View file →
@@ -1,0 +1,176 @@
1 +<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2 +
3 +if ( ! defined( 'ABSPATH' ) ) {
4 + exit( 0 );
5 +}
6 +
7 +new WPCOM_JSON_API_GET_Post_Counts_V1_1_Endpoint(
8 + array(
9 + 'description' => 'Get number of posts in the post type groups by post status',
10 + 'group' => 'sites',
11 + 'stat' => 'sites:X:post-counts:X',
12 + 'force' => 'wpcom',
13 + 'method' => 'GET',
14 + 'min_version' => '1.1',
15 + 'max_version' => '1.2',
16 + 'path' => '/sites/%s/post-counts/%s',
17 + 'path_labels' => array(
18 + '$site' => '(int|string) Site ID or domain',
19 + '$post_type' => '(string) Post Type',
20 + ),
21 +
22 + 'query_parameters' => array(
23 + 'context' => false,
24 + 'author' => '(int) author ID',
25 + ),
26 +
27 + 'example_request' => 'https://public-api.wordpress.com/rest/v1.2/sites/en.blog.wordpress.com/post-counts/page',
28 +
29 + 'response_format' => array(
30 + 'counts' => array(
31 + 'all' => '(array) Number of posts by any author in the post type grouped by post status',
32 + 'mine' => '(array) Number of posts by the current user in the post type grouped by post status',
33 + ),
34 + ),
35 + )
36 +);
37 +
38 +/**
39 + * GET Post Counts v1_1 endpoint class.
40 + *
41 + * @phan-constructor-used-for-side-effects
42 + */
43 +class WPCOM_JSON_API_GET_Post_Counts_V1_1_Endpoint extends WPCOM_JSON_API_Endpoint {
44 +
45 + /**
46 + * Whitelist array.
47 + *
48 + * @var string[]
49 + */
50 + private $allowlist = array( 'publish' );
51 +
52 + /**
53 + * Build SQL query
54 + *
55 + * This function must `$wpdb->prepare` the query. The return is expected to be prepared by consuming functions.
56 + *
57 + * @param string $post_type - post type.
58 + * @param int $user_id - the user ID.
59 + * @return string SQL query
60 + */
61 + private function buildCountsQuery( $post_type = 'post', $user_id = null ) {
62 + global $wpdb;
63 +
64 + $query = 'SELECT post_status as status, count(*) as count ';
65 + $query .= "FROM {$wpdb->posts} ";
66 + $query .= 'WHERE post_type = %s ';
67 + if ( isset( $user_id ) ) {
68 + $query .= 'AND post_author = %d ';
69 + }
70 +
71 + $query .= 'GROUP BY status';
72 +
73 + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- This is properly prepared, except the query is constructed in the variable, throwing the PHPCS error.
74 + return $wpdb->prepare( $query, $post_type, $user_id );
75 + }
76 +
77 + /**
78 + * Retrive counts using wp_cache
79 + *
80 + * @param string $post_type - thge post type.
81 + * @param int $id - the ID.
82 + */
83 + private function retrieveCounts( $post_type, $id = null ) {
84 + if ( ! isset( $id ) ) {
85 + $counts = array();
86 + foreach ( (array) wp_count_posts( $post_type ) as $status => $count ) {
87 + if ( in_array( $status, $this->allowlist, true ) && $count > 0 ) {
88 + $counts[ $status ] = (int) $count;
89 + }
90 + }
91 +
92 + return $counts;
93 + }
94 +
95 + global $wpdb;
96 + $key = 'rest-api-' . $id . '-' . _count_posts_cache_key( $post_type );
97 + $counts = wp_cache_get( $key, 'counts' );
98 +
99 + if ( false === $counts ) {
100 + // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- buildCountsQuery prepares the query.
101 + $results = $wpdb->get_results( $this->buildCountsQuery( $post_type, $id ) );
102 + $counts = $this->filterStatusesByWhiteslist( $results );
103 + wp_cache_set( $key, $counts, 'counts' );
104 + }
105 +
106 + return $counts;
107 + }
108 +
109 + /**
110 + * Filter statuses by whiteslist.
111 + *
112 + * @param array $in - the post we're checking.
113 + */
114 + private function filterStatusesByWhiteslist( $in ) {
115 + $return = array();
116 + foreach ( $in as $result ) {
117 + if ( in_array( $result->status, $this->allowlist, true ) ) {
118 + $return[ $result->status ] = (int) $result->count;
119 + }
120 + }
121 + return $return;
122 + }
123 +
124 + /**
125 + *
126 + * API callback.
127 + *
128 + * /sites/%s/post-counts/%s
129 + *
130 + * @param string $path - the path.
131 + * @param int $blog_id - the blog ID.
132 + * @param string $post_type - the post type.
133 + */
134 + public function callback( $path = '', $blog_id = 0, $post_type = 'post' ) {
135 + if ( ! get_current_user_id() ) {
136 + return new WP_Error( 'authorization_required', __( 'An active access token must be used to retrieve post counts.', 'jetpack' ), 403 );
137 + }
138 +
139 + $blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ), false );
140 +
141 + if ( is_wp_error( $blog_id ) ) {
142 + return $blog_id;
143 + }
144 +
145 + // @todo see if we can use a strict comparison here.
146 + if ( ! in_array( $post_type, array( 'post', 'revision', 'page', 'any' ), true ) && defined( 'IS_WPCOM' ) && IS_WPCOM ) {
147 + $this->load_theme_functions();
148 + }
149 +
150 + if ( ! post_type_exists( $post_type ) ) {
151 + return new WP_Error( 'unknown_post_type', __( 'Unknown post type requested.', 'jetpack' ), 404 );
152 + }
153 +
154 + $args = $this->query_args();
155 + $mine_ID = get_current_user_id(); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
156 +
157 + if ( current_user_can( 'edit_posts' ) ) {
158 + array_push( $this->allowlist, 'draft', 'future', 'pending', 'private', 'trash' );
159 + }
160 +
161 + $return = array(
162 + 'counts' => array(
163 + 'all' => (object) $this->retrieveCounts( $post_type ),
164 + 'mine' => (object) $this->retrieveCounts( $post_type, $mine_ID ), // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
165 + ),
166 + );
167 +
168 + // Author.
169 + if ( isset( $args['author'] ) ) {
170 + $author_ID = $args['author']; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
171 + $return['counts']['author'] = (object) $this->retrieveCounts( $post_type, $author_ID ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
172 + }
173 +
174 + return (object) $return;
175 + }
176 +}