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-backup/src/rest/class-activity-log-bridge.php +145 -0 16.2-beta → 16.3 View file →
@@ -1,0 +1,145 @@
1 +<?php
2 +/**
3 + * Activity log REST bridge — proxies /sites/{id}/activity/rewindable.
4 + *
5 + * @package automattic/jetpack-backup-plugin
6 + */
7 +
8 +namespace Automattic\Jetpack\Backup\V0005\REST;
9 +
10 +use Automattic\Jetpack\Connection\Client;
11 +use WP_Error;
12 +use WP_REST_Request;
13 +use WP_REST_Server;
14 +
15 +if ( ! defined( 'ABSPATH' ) ) {
16 + exit( 0 );
17 +}
18 +
19 +/**
20 + * Powers the modernized Overview's activity list. Forwards the raw
21 + * WPCOM rewindable-activity response; the React layer's
22 + * `normalize/activity-log.ts` converts entries to `ActivityItem` shape.
23 + */
24 +class Activity_Log_Bridge {
25 +
26 + /**
27 + * Register routes.
28 + *
29 + * @return void
30 + */
31 + public static function register_routes() {
32 + // NOTE: not `/activity-log` — that namespace is owned by the
33 + // `automattic/jetpack-activity-log` package's REST controller,
34 + // which is loaded inside the Jetpack plugin. Sharing the route
35 + // would let `register_rest_route`'s endpoint-merge pick the
36 + // wrong handler at dispatch time (the two bridges proxy
37 + // different WPCOM endpoints with different response shapes).
38 + register_rest_route(
39 + 'jetpack/v4',
40 + '/site/rewindable-activity',
41 + array(
42 + 'methods' => WP_REST_Server::READABLE,
43 + 'callback' => array( __CLASS__, 'get_activity_log' ),
44 + 'permission_callback' => array( Rest_Controller::class, 'permission_check' ),
45 + // Bounds mirror what WPCOM's own `get_stream_args()`
46 + // validate_callback enforces on `/activity/rewindable`, and
47 + // the sibling `jetpack-activity-log` package's declaration.
48 + // Declaring them here turns an out-of-range value into a 400
49 + // with a useful message instead of a round-trip that WPCOM
50 + // rejects.
51 + 'args' => array(
52 + 'number' => array(
53 + 'description' => __( 'Number of items to return per page.', 'jetpack-backup-pkg' ),
54 + 'type' => 'integer',
55 + 'minimum' => 1,
56 + 'maximum' => 1000,
57 + ),
58 + 'page' => array(
59 + 'description' => __( '1-indexed page number.', 'jetpack-backup-pkg' ),
60 + 'type' => 'integer',
61 + 'minimum' => 1,
62 + ),
63 + // Direction only: WPCOM's `get_stream_args()` sorts on `ts_utc`
64 + // and takes no field, so there is no `orderby` to declare.
65 + 'sort_order' => array(
66 + 'description' => __( 'Sort direction.', 'jetpack-backup-pkg' ),
67 + 'type' => 'string',
68 + 'enum' => array( 'asc', 'desc' ),
69 + ),
70 + ),
71 + )
72 + );
73 + }
74 +
75 + /**
76 + * Proxy the WPCOM rewindable activity log.
77 + *
78 + * Forwards `number` (per page) and `page` (1-indexed) so the dashboard
79 + * paginates against the real server response — `totalItems` /
80 + * `totalPages` come back in the WPCOM envelope and drive DataViews'
81 + * pagination footer. Same param shape the `automattic/jetpack-activity-log`
82 + * package uses against the parent `/sites/{id}/activity` endpoint.
83 + *
84 + * `sort_order` is forwarded too, so the list's Order control reorders
85 + * the real result set rather than the ten rows already on screen.
86 + * Omitted when absent: WPCOM defaults it to `desc`.
87 + *
88 + * @param WP_REST_Request $request The REST request.
89 + * @return \WP_REST_Response|WP_Error
90 + */
91 + public static function get_activity_log( WP_REST_Request $request ) {
92 + $blog_id = Rest_Controller::get_blog_id_or_error();
93 + if ( is_wp_error( $blog_id ) ) {
94 + return $blog_id;
95 + }
96 +
97 + $query = array_filter(
98 + array(
99 + 'number' => $request->get_param( 'number' ),
100 + 'page' => $request->get_param( 'page' ),
101 + 'sort_order' => $request->get_param( 'sort_order' ),
102 + // Activity summaries are rendered by WPCOM. Without this they
103 + // come back in English whatever the reader's language is.
104 + '_locale' => get_user_locale(),
105 + ),
106 + static function ( $value ) {
107 + return null !== $value && '' !== $value;
108 + }
109 + );
110 +
111 + $endpoint = sprintf( '/sites/%d/activity/rewindable', $blog_id );
112 + if ( ! empty( $query ) ) {
113 + $endpoint .= '?' . http_build_query( $query );
114 + }
115 +
116 + $response = Client::wpcom_json_api_request_as_user(
117 + $endpoint,
118 + 'v2',
119 + array(),
120 + null,
121 + 'wpcom'
122 + );
123 +
124 + if ( is_wp_error( $response ) ) {
125 + return Rest_Controller::transport_error( $response, 'activity_log_fetch_failed' );
126 + }
127 +
128 + // Cast because `wp_remote_retrieve_response_code()` hands back
129 + // whatever the transport put there, and a numeric string fails the
130 + // strict comparison below — routing a perfectly good response into
131 + // the failure branch, where `upstream_error()`'s clamp then reports
132 + // it as a 500. Same reasoning at every bridge; the long version is
133 + // on `Rest_Controller::upstream_error()`.
134 + $status_code = (int) wp_remote_retrieve_response_code( $response );
135 + if ( 200 !== $status_code ) {
136 + return Rest_Controller::upstream_error(
137 + $response,
138 + 'activity_log_fetch_failed',
139 + __( 'Could not fetch the site activity log.', 'jetpack-backup-pkg' )
140 + );
141 + }
142 +
143 + return rest_ensure_response( json_decode( wp_remote_retrieve_body( $response ), true ) );
144 + }
145 +}