summaryrefslogtreecommitdiff
blob: 5e83b41db03ab820603ef0cf527cc4f58bbbc581 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<?php

new WPCOM_JSON_API_GET_Post_Counts_V1_1_Endpoint( array(
	'description'   => 'Get number of posts in the post type groups by post status',
	'group'         => 'sites',
	'stat'          => 'sites:X:post-counts:X',
	'force'         => 'wpcom',
	'method'        => 'GET',
	'min_version'   => '1.1',
	'max_version'   => '1.2',
	'path'          => '/sites/%s/post-counts/%s',
	'path_labels'   => array(
		'$site'       => '(int|string) Site ID or domain',
		'$post_type'  => '(string) Post Type',
	),

	'query_parameters' => array(
		'context' => false,
		'author' => '(int) author ID',
	),

	'example_request' => 'https://public-api.wordpress.com/rest/v1.2/sites/en.blog.wordpress.com/post-counts/page',

	'response_format' => array(
		'counts' => array(
			'all' => '(array) Number of posts by any author in the post type grouped by post status',
			'mine' => '(array) Number of posts by the current user in the post type grouped by post status'
		)
	)
) );

class WPCOM_JSON_API_GET_Post_Counts_V1_1_Endpoint extends WPCOM_JSON_API_Endpoint {

	private $whitelist = array( 'publish' );

	/**
 	 * Build SQL query
 	 *
 	 * @param {String} type - post type
 	 * @param {Number} [author]
 	 * @return {String} SQL query
 	 */
	private function buildCountsQuery( $post_type = 'post', $user_id = null ) {
		global $wpdb;

		$query = "SELECT post_status as status, count(*) as count ";
		$query .= "FROM {$wpdb->posts} ";
		$query .= "WHERE post_type = %s ";
		if ( isset( $user_id ) ) {
			$query .= "AND post_author = %d ";
		}

		$query .= "GROUP BY status";

		return $wpdb->prepare( $query, $post_type, $user_id );
	}

	/**
 	 * Retrive counts using wp_cache
 	 *
 	 * @param {String} $post_type
 	 * @param {Number} [$id]
 	 */
	private function retrieveCounts( $post_type, $id = null) {
		if ( ! isset( $id ) ) {
			$counts = array();
			foreach( (array) wp_count_posts( $post_type ) as $status => $count ) {
				if ( in_array( $status, $this->whitelist ) && $count > 0 ) {
					$counts[ $status ] = (int) $count;
				}
			};

			return $counts;
		}

		global $wpdb;
		$key = 'rest-api-' . $id . '-' . _count_posts_cache_key( $post_type );
		$counts = wp_cache_get( $key, 'counts' );

		if ( false === $counts ) {
			$results = $wpdb->get_results( $this->buildCountsQuery( $post_type, $id ) );
			$counts = $this->filterStatusesByWhiteslist( $results );
			wp_cache_set( $key, $counts, 'counts' );
		}

		return $counts;
	}

	private function filterStatusesByWhiteslist( $in ) {
		$return = array();
		foreach( $in as $result) {
			if ( in_array( $result->status, $this->whitelist ) ) {
				$return[ $result->status ] = (int) $result->count;
			}
		};
		return $return;
	}

	// /sites/%s/post-counts/%s
	public function callback( $path = '', $blog_id = 0, $post_type = 'post' ) {
		if ( ! get_current_user_id() ) {
			return new WP_Error( 'authorization_required', __( 'An active access token must be used to retrieve post counts.', 'jetpack' ), 403 );
		}

		$blog_id = $this->api->switch_to_blog_and_validate_user( $this->api->get_blog_id( $blog_id ), false );

		if ( is_wp_error( $blog_id ) ) {
			return $blog_id;
		}

		if ( ! post_type_exists( $post_type ) ) {
			return new WP_Error( 'unknown_post_type', __( 'Unknown post type requested.', 'jetpack' ), 404 );
		}

		$args = $this->query_args();
		$mine_ID = get_current_user_id();

		if ( current_user_can( 'edit_posts' ) ) {
			array_push( $this->whitelist, 'draft', 'future', 'pending', 'private', 'trash' );
		}

		$return = array(
			'counts' => (array) array(
				'all' => (object) $this->retrieveCounts( $post_type ),
				'mine' => (object) $this->retrieveCounts( $post_type, $mine_ID ),
			)
		);

		// AUTHOR
		if ( isset( $args['author'] ) ) {
			$author_ID = $args['author'];
			$return['counts']['author'] = (object) $this->retrieveCounts( $post_type, $author_ID );
		}

		return (object) $return;
	}
}