← 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 | +} | |