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 | jetpack_vendor/automattic/jetpack-videopress/src/class-rest-controller.php +175 -0 16.2-beta → 16.3 View file →
@@ -1,0 +1,175 @@
1 +<?php
2 +/**
3 + * The VideoPress REST Controller.
4 + *
5 + * Registers the `/jetpack/v4/videopress/*` routes backing the
6 + * modernized wp-build dashboard. Currently exposes one route — a
7 + * user-signed proxy to the WPCOM `sites/{id}/stats/video-plays`
8 + * endpoint — needed by the Overview screen's KPI / trends / top-N
9 + * cards.
10 + *
11 + * @package automattic/jetpack-videopress
12 + */
13 +
14 +namespace Automattic\Jetpack\VideoPress;
15 +
16 +use Automattic\Jetpack\Connection\Client;
17 +use Jetpack_Options;
18 +use WP_Error;
19 +use WP_REST_Request;
20 +use WP_REST_Server;
21 +
22 +/**
23 + * REST routes for the modernized VideoPress admin UI.
24 + */
25 +class Rest_Controller {
26 +
27 + /**
28 + * REST namespace used by this package's modernization routes.
29 + *
30 + * @var string
31 + */
32 + const REST_NAMESPACE = 'jetpack/v4/videopress';
33 +
34 + /**
35 + * Hook the route registration on `rest_api_init`.
36 + *
37 + * @return void
38 + */
39 + public static function init() {
40 + add_action( 'rest_api_init', array( __CLASS__, 'register_rest_routes' ) );
41 + }
42 +
43 + /**
44 + * Register the VideoPress REST routes.
45 + *
46 + * @return void
47 + */
48 + public static function register_rest_routes() {
49 + register_rest_route(
50 + self::REST_NAMESPACE,
51 + '/stats/video-plays',
52 + array(
53 + 'methods' => WP_REST_Server::READABLE,
54 + 'callback' => array( __CLASS__, 'get_stats_video_plays' ),
55 + 'permission_callback' => array( __CLASS__, 'permissions_callback' ),
56 + 'args' => self::stats_video_plays_args(),
57 + )
58 + );
59 + }
60 +
61 + /**
62 + * Query params accepted by the video-plays proxy. Forwarded verbatim
63 + * to WPCOM after permission and shape validation. `complete_stats` and
64 + * `check_stats_module` are always forced by the callback and are
65 + * therefore not exposed as incoming params.
66 + *
67 + * @return array
68 + */
69 + private static function stats_video_plays_args() {
70 + return array(
71 + 'period' => array(
72 + 'description' => __( 'Period unit: day, week, month, or year.', 'jetpack-videopress-pkg' ),
73 + 'type' => 'string',
74 + 'enum' => array( 'day', 'week', 'month', 'year' ),
75 + ),
76 + 'num' => array(
77 + 'description' => __( 'Number of periods to include.', 'jetpack-videopress-pkg' ),
78 + 'type' => 'integer',
79 + 'minimum' => 1,
80 + 'maximum' => 365,
81 + ),
82 + 'date' => array(
83 + 'description' => __( 'Most recent day to include in results (YYYY-MM-DD).', 'jetpack-videopress-pkg' ),
84 + 'type' => 'string',
85 + 'format' => 'date',
86 + ),
87 + 'start_date' => array(
88 + 'description' => __( 'Starting date for range queries (YYYY-MM-DD).', 'jetpack-videopress-pkg' ),
89 + 'type' => 'string',
90 + 'format' => 'date',
91 + ),
92 + );
93 + }
94 +
95 + /**
96 + * Permission callback. Admin-gated. The upstream call is blog-signed,
97 + * matching the existing `Stats::fetch_video_plays` path; no user-level
98 + * WPCOM connection is required.
99 + *
100 + * @return bool
101 + */
102 + public static function permissions_callback() {
103 + return current_user_can( 'manage_options' );
104 + }
105 +
106 + /**
107 + * Proxy the video-plays stats endpoint.
108 + *
109 + * Forwards the allowed query params to WPCOM (REST v1.1, blog-signed
110 + * — matching the existing `Stats::fetch_video_plays` path) and forces
111 + * `complete_stats=true`. `check_stats_module=false` is also forced so the
112 + * report loads for standalone VideoPress sites without the Jetpack Stats
113 + * module active, matching `Stats::fetch_video_plays`. In complete-stats
114 + * mode, each day entry carries
115 + * `total.views`, `total.impressions`, and `total.watch_time` (in hours)
116 + * plus a per-video `data[]` array whose entries have `post_id`, `title`,
117 + * `views`, `impressions`, `watch_time` (hours), and `retention_rate`.
118 + * The `plays` field is NOT returned in complete-stats mode.
119 + *
120 + * @param WP_REST_Request $request Incoming request.
121 + * @return mixed Decoded JSON response from WPCOM, or WP_Error on failure.
122 + */
123 + public static function get_stats_video_plays( WP_REST_Request $request ) {
124 + $blog_id = (int) Jetpack_Options::get_option( 'id' );
125 + if ( ! $blog_id ) {
126 + return new WP_Error(
127 + 'videopress_stats_not_connected',
128 + esc_html__( 'This site is not connected to WordPress.com.', 'jetpack-videopress-pkg' ),
129 + array( 'status' => 400 )
130 + );
131 + }
132 +
133 + $params = array(
134 + 'complete_stats' => 'true',
135 + 'check_stats_module' => 'false',
136 + );
137 + foreach ( array_keys( self::stats_video_plays_args() ) as $key ) {
138 + $value = $request->get_param( $key );
139 + if ( $value !== null && $value !== '' ) {
140 + $params[ $key ] = $value;
141 + }
142 + }
143 +
144 + $path = sprintf(
145 + 'sites/%d/stats/video-plays?%s',
146 + $blog_id,
147 + http_build_query( $params )
148 + );
149 + $response = Client::wpcom_json_api_request_as_blog( $path );
150 +
151 + if ( is_wp_error( $response ) ) {
152 + return new WP_Error(
153 + 'videopress_stats_request_failed',
154 + $response->get_error_message(),
155 + array( 'status' => 500 )
156 + );
157 + }
158 +
159 + $status = (int) wp_remote_retrieve_response_code( $response );
160 + $body = json_decode( wp_remote_retrieve_body( $response ), true );
161 +
162 + if ( 200 !== $status ) {
163 + $message = is_array( $body ) && isset( $body['message'] )
164 + ? (string) $body['message']
165 + : esc_html__( 'Unable to fetch VideoPress stats.', 'jetpack-videopress-pkg' );
166 + return new WP_Error(
167 + 'videopress_stats_request_failed',
168 + $message,
169 + array( 'status' => $status ? $status : 500 )
170 + );
171 + }
172 +
173 + return rest_ensure_response( $body );
174 + }
175 +}