PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-a.3
Jetpack – WP Security, Backup, Speed, & Growth v16.3-a.3
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 13.7.2 13.8.3 All 506 releases
jetpack / json-endpoints / class.wpcom-json-api-get-post-counts-v1-1-endpoint.php

class.wpcom-json-api-get-post-counts-v1-1-endpoint.php in Jetpack – WP Security, Backup, Speed, & Growth 16.3-a.3, at json-endpoints/class.wpcom-json-api-get-post-counts-v1-1-endpoint.php

177 lines 5.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 }
177