Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 75
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
X_Usage_Controller
0.00% covered (danger)
0.00%
0 / 75
0.00% covered (danger)
0.00%
0 / 5
156
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
 register_routes
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
2
 get_items_permissions_check
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 get_items
0.00% covered (danger)
0.00%
0 / 28
0.00% covered (danger)
0.00%
0 / 1
56
 get_item_schema
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2/**
3 * X Usage Controller.
4 *
5 * Exposes X share usage data as a collection.
6 *
7 * @package automattic/jetpack-publicize
8 */
9
10namespace Automattic\Jetpack\Publicize\REST_API;
11
12use Automattic\Jetpack\Connection\Traits\WPCOM_REST_API_Proxy_Request;
13use Automattic\Jetpack\Publicize\Publicize_Utils as Utils;
14use WP_REST_Request;
15use WP_REST_Response;
16use WP_REST_Server;
17
18/**
19 * X Usage Controller class.
20 *
21 * @phan-constructor-used-for-side-effects
22 */
23class X_Usage_Controller extends Base_Controller {
24
25    use WPCOM_REST_API_Proxy_Request;
26
27    /**
28     * Constructor.
29     */
30    public function __construct() {
31        parent::__construct();
32
33        $this->base_api_path = 'wpcom';
34        $this->version       = 'v2';
35
36        $this->namespace = "{$this->base_api_path}/{$this->version}";
37        $this->rest_base = 'publicize/x-usage';
38
39        $this->allow_requests_as_blog = true;
40
41        add_action( 'rest_api_init', array( $this, 'register_routes' ) );
42    }
43
44    /**
45     * Register the routes.
46     */
47    public function register_routes() {
48        register_rest_route(
49            $this->namespace,
50            '/' . $this->rest_base,
51            array(
52                array(
53                    'methods'             => WP_REST_Server::READABLE,
54                    'callback'            => array( $this, 'get_items' ),
55                    'permission_callback' => array( $this, 'get_items_permissions_check' ),
56                ),
57                'schema' => array( $this, 'get_public_item_schema' ),
58            )
59        );
60    }
61
62    /**
63     * Check permissions.
64     *
65     * @param WP_REST_Request $request Full details about the request.
66     * @return true|\WP_Error
67     */
68    public function get_items_permissions_check( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
69        return $this->publicize_permissions_check();
70    }
71
72    /**
73     * Get X usage data as a collection.
74     *
75     * Returns an array of usage items, one per period. For paid plans,
76     * each item represents a calendar month (id = yyyy-mm). For free
77     * plans, a single item with id = 'free' covers lifetime usage.
78     *
79     * @param WP_REST_Request $request Full details about the request.
80     * @return WP_REST_Response
81     */
82    public function get_items( $request ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
83        if ( Utils::is_wpcom() ) {
84            require_lib( 'publicize/util/x-usage' );
85
86            $usage = \Publicize\get_x_usage( get_current_blog_id() );
87
88            $items = array();
89            foreach ( $usage as $period => $entries ) {
90                if ( ! is_array( $entries ) || empty( $entries ) ) {
91                    continue;
92                }
93
94                $used    = 0;
95                $pending = 0;
96                foreach ( $entries as $entry ) {
97                    if ( 'done' === ( $entry['status'] ?? '' ) ) {
98                        ++$used;
99                    } else {
100                        ++$pending;
101                    }
102                }
103
104                $item = array(
105                    'period'  => $period,
106                    'used'    => $used,
107                    'pending' => $pending,
108                    'total'   => $used + $pending,
109                );
110
111                $data    = $this->prepare_item_for_response( $item, $request );
112                $items[] = $this->prepare_response_for_collection( $data );
113            }
114
115            $response = rest_ensure_response( $items );
116            $response->header( 'X-WP-Total', (string) count( $items ) );
117            $response->header( 'X-WP-TotalPages', '1' );
118
119            return $response;
120        }
121
122        return rest_ensure_response(
123            $this->proxy_request_to_wpcom_as_blog( $request )
124        );
125    }
126
127    /**
128     * Schema for the endpoint.
129     *
130     * @return array
131     */
132    public function get_item_schema() {
133        if ( $this->schema ) {
134            return $this->add_additional_fields_schema( $this->schema );
135        }
136
137        $schema = array(
138            '$schema'    => 'http://json-schema.org/draft-04/schema#',
139            'title'      => 'publicize-x-usage',
140            'type'       => 'object',
141            'properties' => array(
142                'period'  => array(
143                    'type'        => 'string',
144                    'description' => __( 'Period identifier: yyyy-mm for paid plans, "free" for free plans.', 'jetpack-publicize-pkg' ),
145                ),
146                'used'    => array(
147                    'type'        => 'integer',
148                    'description' => __( 'Number of shares successfully sent.', 'jetpack-publicize-pkg' ),
149                ),
150                'pending' => array(
151                    'type'        => 'integer',
152                    'description' => __( 'Number of shares scheduled or awaiting publish.', 'jetpack-publicize-pkg' ),
153                ),
154                'total'   => array(
155                    'type'        => 'integer',
156                    'description' => __( 'Total shares counting toward quota (used + pending).', 'jetpack-publicize-pkg' ),
157                ),
158            ),
159        );
160
161        $this->schema = $schema;
162
163        return $this->add_additional_fields_schema( $schema );
164    }
165}