From 3ed3de86a58730377bbc29f8b7df7aa7729f28ce Mon Sep 17 00:00:00 2001 From: Michael Turk Date: Tue, 18 Jun 2019 13:27:09 -0400 Subject: [PATCH] Move Jetpack_Client to Connection package as Client (#12717) * move Jetpack_Client to Connection package as Client * Moving the client library to packages explicitly. * Adding Michael's changes back to the file. * Apply PHPCS recommendations. * Introduce the Jetpack_Constants package usage. * Fix references to methods outside of the namespace. * Remove explicit require statements for the connection client. --- _inc/class.jetpack-provision.php | 6 +- _inc/lib/class.core-rest-api-endpoints.php | 13 +- .../class.jetpack-core-api-site-endpoints.php | 5 +- .../core-api/wpcom-endpoints/memberships.php | 6 +- _inc/lib/debugger/class-jetpack-cxn-tests.php | 5 +- class.jetpack-cli.php | 12 +- class.jetpack-client-server.php | 3 +- class.jetpack-ixr-client.php | 4 +- class.jetpack-network.php | 4 +- class.jetpack-plan.php | 6 +- class.jetpack-xmlrpc-server.php | 4 +- class.jetpack.php | 7 +- class.json-api-endpoints.php | 4 +- composer.lock | 11 +- functions.global.php | 4 +- jetpack.php | 1 - ...tpack-json-api-themes-install-endpoint.php | 4 +- modules/protect/blocked-login-page.php | 5 +- modules/search/class.jetpack-search.php | 6 +- modules/stats.php | 9 +- modules/videopress/class.videopress-ajax.php | 4 +- .../class.videopress-edit-attachment.php | 7 +- modules/videopress/utility-functions.php | 4 +- modules/wordads/php/api.php | 6 +- .../connection/src/Client.php | 304 +++++++++++------- packages/jitm/src/JITM.php | 5 +- 26 files changed, 282 insertions(+), 167 deletions(-) rename class.jetpack-client.php => packages/connection/src/Client.php (52%) diff --git a/_inc/class.jetpack-provision.php b/_inc/class.jetpack-provision.php index 819a77d588b04..440d6ea0a4768 100644 --- a/_inc/class.jetpack-provision.php +++ b/_inc/class.jetpack-provision.php @@ -1,5 +1,7 @@ $calypso_env ), $url ); } - $result = Jetpack_Client::_wp_remote_request( $url, $request ); + $result = Client::_wp_remote_request( $url, $request ); if ( is_wp_error( $result ) ) { return $result; @@ -258,7 +260,7 @@ private static function verify_token( $access_token ) { ); $url = sprintf( 'https://%s/rest/v1.3/jpphp/partner-keys/verify', self::get_api_host() ); - $result = Jetpack_Client::_wp_remote_request( $url, $request ); + $result = Client::_wp_remote_request( $url, $request ); if ( is_wp_error( $result ) ) { return $result; diff --git a/_inc/lib/class.core-rest-api-endpoints.php b/_inc/lib/class.core-rest-api-endpoints.php index 22b7064e9fb1d..9b752f345fad4 100644 --- a/_inc/lib/class.core-rest-api-endpoints.php +++ b/_inc/lib/class.core-rest-api-endpoints.php @@ -1,5 +1,6 @@ true, // Default to opt-out if not connected to wp.com. ); } else { - $response = Jetpack_Client::wpcom_json_api_request_as_user( + $response = Client::wpcom_json_api_request_as_user( '/jetpack-user-tracking', 'v2', array( @@ -1291,7 +1292,7 @@ public static function update_user_tracking_settings( $request ) { 'tracks_opt_out' => true, // Default to opt-out if not connected to wp.com. ); } else { - $response = Jetpack_Client::wpcom_json_api_request_as_user( + $response = Client::wpcom_json_api_request_as_user( '/jetpack-user-tracking', 'v2', array( @@ -1333,7 +1334,7 @@ public static function site_data() { $args['headers']['Cookie'] = "store_sandbox=$secret;"; } - $response = Jetpack_Client::wpcom_json_api_request_as_blog( sprintf( '/sites/%d', $site_id ) .'?force=wpcom', '1.1', $args ); + $response = Client::wpcom_json_api_request_as_blog( sprintf( '/sites/%d', $site_id ) .'?force=wpcom', '1.1', $args ); if ( 200 !== wp_remote_retrieve_response_code( $response ) ) { return new WP_Error( 'site_data_fetch_failed' ); @@ -1390,7 +1391,7 @@ public static function get_site_activity() { ); } - $response = Jetpack_Client::wpcom_json_api_request_as_user( "/sites/$site_id/activity", '2', array( + $response = Client::wpcom_json_api_request_as_user( "/sites/$site_id/activity", '2', array( 'method' => 'GET', 'headers' => array( 'X-Forwarded-For' => Jetpack::current_user_ip( true ), diff --git a/_inc/lib/core-api/class.jetpack-core-api-site-endpoints.php b/_inc/lib/core-api/class.jetpack-core-api-site-endpoints.php index 68327f513c2c2..c79ef3f9b61cb 100644 --- a/_inc/lib/core-api/class.jetpack-core-api-site-endpoints.php +++ b/_inc/lib/core-api/class.jetpack-core-api-site-endpoints.php @@ -1,4 +1,7 @@ to_array(); } else { $blog_id = Jetpack_Options::get_option( 'id' ); - $response = Jetpack_Client::wpcom_json_api_request_as_user( + $response = Client::wpcom_json_api_request_as_user( "/sites/$blog_id/{$this->rest_base}/product", 'v2', array( @@ -150,7 +152,7 @@ public function get_status() { return (array) get_memberships_settings_for_site( $blog_id ); } else { $blog_id = Jetpack_Options::get_option( 'id' ); - $response = Jetpack_Client::wpcom_json_api_request_as_user( + $response = Client::wpcom_json_api_request_as_user( "/sites/$blog_id/{$this->rest_base}/status", 'v2', array(), diff --git a/_inc/lib/debugger/class-jetpack-cxn-tests.php b/_inc/lib/debugger/class-jetpack-cxn-tests.php index b8dc0949a219b..31c8ea8938904 100644 --- a/_inc/lib/debugger/class-jetpack-cxn-tests.php +++ b/_inc/lib/debugger/class-jetpack-cxn-tests.php @@ -5,6 +5,7 @@ * @package Jetpack */ +use Automattic\Jetpack\Connection\Client; /** * Class Jetpack_Cxn_Tests contains all of the actual tests. @@ -226,9 +227,9 @@ protected function test__wpcom_connection_test() { return self::skipped_test( $name ); } - $response = Jetpack_Client::wpcom_json_api_request_as_blog( + $response = Client::wpcom_json_api_request_as_blog( sprintf( '/jetpack-blogs/%d/test-connection', Jetpack_Options::get_option( 'id' ) ), - Jetpack_Client::WPCOM_JSON_API_VERSION + Client::WPCOM_JSON_API_VERSION ); if ( is_wp_error( $response ) ) { diff --git a/class.jetpack-cli.php b/class.jetpack-cli.php index 037dd2354aec0..dfedf0124ba20 100644 --- a/class.jetpack-cli.php +++ b/class.jetpack-cli.php @@ -2,6 +2,8 @@ WP_CLI::add_command( 'jetpack', 'Jetpack_CLI' ); +use Automattic\Jetpack\Connection\Client; + /** * Control your local Jetpack installation. * @@ -130,9 +132,9 @@ public function test_connection( $args, $assoc_args ) { WP_CLI::error( __( 'Jetpack is not currently connected to WordPress.com', 'jetpack' ) ); } - $response = Jetpack_Client::wpcom_json_api_request_as_blog( + $response = Client::wpcom_json_api_request_as_blog( sprintf( '/jetpack-blogs/%d/test-connection', Jetpack_Options::get_option( 'id' ) ), - Jetpack_Client::WPCOM_JSON_API_VERSION + Client::WPCOM_JSON_API_VERSION ); if ( is_wp_error( $response ) ) { @@ -1120,7 +1122,7 @@ public function partner_cancel( $args, $named_args ) { $url = esc_url_raw( add_query_arg( 'partner_tracking_id', $named_args['partner_tracking_id'], $url ) ); } - $result = Jetpack_Client::_wp_remote_request( $url, $request ); + $result = Client::_wp_remote_request( $url, $request ); Jetpack_Options::delete_option( 'onboarding' ); @@ -1336,9 +1338,9 @@ public function call_api( $args, $named_args ) { ? $named_args['resource'] : sprintf( $named_args['resource'], Jetpack_Options::get_option( 'id' ) ); - $response = Jetpack_Client::wpcom_json_api_request_as_blog( + $response = Client::wpcom_json_api_request_as_blog( $resource_url, - empty( $named_args['api_version'] ) ? Jetpack_Client::WPCOM_JSON_API_VERSION : $named_args['api_version'], + empty( $named_args['api_version'] ) ? Client::WPCOM_JSON_API_VERSION : $named_args['api_version'], $other_args, empty( $decoded_body ) ? null : $decoded_body, empty( $named_args['base_api_path'] ) ? 'rest' : $named_args['base_api_path'] diff --git a/class.jetpack-client-server.php b/class.jetpack-client-server.php index 5001ef43e1a77..4e66979a4b8c2 100644 --- a/class.jetpack-client-server.php +++ b/class.jetpack-client-server.php @@ -1,5 +1,6 @@ 'application/json', ), ); - $response = Jetpack_Client::_wp_remote_request( Jetpack::fix_url_for_bad_hosts( Jetpack::api_url( 'token' ) ), $args ); + $response = Client::_wp_remote_request( Jetpack::fix_url_for_bad_hosts( Jetpack::api_url( 'token' ) ), $args ); if ( is_wp_error( $response ) ) { return new Jetpack_Error( 'token_http_request_failed', $response->get_error_message() ); diff --git a/class.jetpack-ixr-client.php b/class.jetpack-ixr-client.php index 5d2f7516a8326..59f0b4889235d 100644 --- a/class.jetpack-ixr-client.php +++ b/class.jetpack-ixr-client.php @@ -2,6 +2,8 @@ defined( 'ABSPATH' ) or die( 'No direct access, please.' ); +use Automattic\Jetpack\Connection\Client; + require_once( ABSPATH . WPINC . '/class-IXR.php' ); /** @@ -33,7 +35,7 @@ function query() { $request = new IXR_Request( $method, $args ); $xml = trim( $request->getXml() ); - $response = Jetpack_Client::remote_request( $this->jetpack_args, $xml ); + $response = Client::remote_request( $this->jetpack_args, $xml ); if ( is_wp_error( $response ) ) { $this->error = new IXR_Error( -10520, sprintf( 'Jetpack: [%s] %s', $response->get_error_code(), $response->get_error_message() ) ); diff --git a/class.jetpack-network.php b/class.jetpack-network.php index 7b6569f84997c..3047ed8a7cd49 100644 --- a/class.jetpack-network.php +++ b/class.jetpack-network.php @@ -1,5 +1,7 @@ 'GET' ), true diff --git a/class.jetpack.php b/class.jetpack.php index 9e2060b4992e9..10b093a79da70 100644 --- a/class.jetpack.php +++ b/class.jetpack.php @@ -1,6 +1,7 @@ 1.1.1 // Check and see if host can verify the Jetpack servers' SSL certificate $args = array(); - Jetpack_Client::_wp_remote_request( + Client::_wp_remote_request( Jetpack::fix_url_for_bad_hosts( Jetpack::api_url( 'test' ) ), $args, true @@ -4470,7 +4471,7 @@ function build_connect_url( $raw = false, $redirect = false, $from = false, $reg if ( ! $last_connect_url_check || ( time() - $last_connect_url_check ) > MINUTE_IN_SECONDS ) { Jetpack_Options::update_raw_option( 'jetpack_last_connect_url_check', time() ); - $response = Jetpack_Client::wpcom_json_api_request_as_blog( + $response = Client::wpcom_json_api_request_as_blog( sprintf( '/sites/%d', $site_id ) .'?force=wpcom', '1.1' ); @@ -5076,7 +5077,7 @@ public static function register() { self::apply_activation_source_to_args( $args['body'] ); - $response = Jetpack_Client::_wp_remote_request( Jetpack::fix_url_for_bad_hosts( Jetpack::api_url( 'register' ) ), $args, true ); + $response = Client::_wp_remote_request( Jetpack::fix_url_for_bad_hosts( Jetpack::api_url( 'register' ) ), $args, true ); // Make sure the response is valid and does not contain any Jetpack errors $registration_details = Jetpack::init()->validate_remote_register_response( $response ); diff --git a/class.json-api-endpoints.php b/class.json-api-endpoints.php index c17e2faacb0f4..897f5b9e5c782 100644 --- a/class.json-api-endpoints.php +++ b/class.json-api-endpoints.php @@ -1,5 +1,7 @@ 'POST' ), diff --git a/composer.lock b/composer.lock index 7a9afc78f675f..427485d3ad7b8 100644 --- a/composer.lock +++ b/composer.lock @@ -381,12 +381,15 @@ "dist": { "type": "path", "url": "./packages/autoloader", - "reference": "8c7dc6036bf6125c31a574c14c6b0521247410ed", + "reference": "43bb413915e6aad7e4a088490cb76d72df22a8fb", "shasum": null }, "require": { "composer-plugin-api": "^1.1" }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5" + }, "type": "composer-plugin", "extra": { "class": "Automattic\\Jetpack\\Autoloader\\CustomAutoloaderPlugin" @@ -396,6 +399,12 @@ "Automattic\\Jetpack\\Autoloader\\": "src" } }, + "scripts": { + "phpunit": [ + "@composer install", + "./vendor/phpunit/phpunit/phpunit --colors=always" + ] + }, "license": [ "GPL-2.0-or-later" ], diff --git a/functions.global.php b/functions.global.php index 44152b19472b9..abbba7bbafebd 100644 --- a/functions.global.php +++ b/functions.global.php @@ -10,6 +10,8 @@ * @package Jetpack */ +use Automattic\Jetpack\Connection\Client; + /** * Disable direct access. */ @@ -153,7 +155,7 @@ function jetpack_theme_update( $preempt, $r, $url ) { // Remove filter to avoid endless loop since wpcom_json_api_request_as_blog uses this too. remove_filter( 'pre_http_request', 'jetpack_theme_update' ); - $result = Jetpack_Client::wpcom_json_api_request_as_blog( + $result = Client::wpcom_json_api_request_as_blog( "themes/download/$theme.zip", '1.1', array( diff --git a/jetpack.php b/jetpack.php index f1a60fde64519..78fe4526e649b 100644 --- a/jetpack.php +++ b/jetpack.php @@ -214,7 +214,6 @@ function jetpack_admin_missing_autoloader() { ?> // @todo: Abstract out the admin functions, and only include them if is_admin() require_once( JETPACK__PLUGIN_DIR . 'class.jetpack.php' ); require_once( JETPACK__PLUGIN_DIR . 'class.jetpack-network.php' ); -require_once( JETPACK__PLUGIN_DIR . 'class.jetpack-client.php' ); require_once( JETPACK__PLUGIN_DIR . 'class.jetpack-data.php' ); require_once( JETPACK__PLUGIN_DIR . 'class.jetpack-client-server.php' ); require_once( JETPACK__PLUGIN_DIR . 'class.jetpack-user-agent.php' ); diff --git a/json-endpoints/jetpack/class.jetpack-json-api-themes-install-endpoint.php b/json-endpoints/jetpack/class.jetpack-json-api-themes-install-endpoint.php index c3cec3d3a51a3..5c69b4dd93265 100644 --- a/json-endpoints/jetpack/class.jetpack-json-api-themes-install-endpoint.php +++ b/json-endpoints/jetpack/class.jetpack-json-api-themes-install-endpoint.php @@ -3,6 +3,8 @@ include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; include_once ABSPATH . 'wp-admin/includes/file.php'; +use Automattic\Jetpack\Connection\Client; + class Jetpack_JSON_API_Themes_Install_Endpoint extends Jetpack_JSON_API_Themes_Endpoint { // POST /sites/%s/themes/%s/install @@ -160,7 +162,7 @@ protected static function download_wpcom_theme_to_file( $theme ) { $url = "themes/download/$theme.zip"; $args = array( 'stream' => true, 'filename' => $file ); - $result = Jetpack_Client::wpcom_json_api_request_as_blog( $url, '1.1', $args ); + $result = Client::wpcom_json_api_request_as_blog( $url, '1.1', $args ); $response = $result[ 'response' ]; if ( $response[ 'code' ] !== 200 ) { diff --git a/modules/protect/blocked-login-page.php b/modules/protect/blocked-login-page.php index 246031f6f3d1c..eb4886922ef52 100644 --- a/modules/protect/blocked-login-page.php +++ b/modules/protect/blocked-login-page.php @@ -1,5 +1,6 @@ $request_body, diff --git a/modules/stats.php b/modules/stats.php index 4a5df01afac59..c40f3968586a0 100644 --- a/modules/stats.php +++ b/modules/stats.php @@ -15,6 +15,7 @@ */ use Automattic\Jetpack\Tracking; +use Automattic\Jetpack\Connection\Client; if ( defined( 'STATS_VERSION' ) ) { return; @@ -684,7 +685,7 @@ function stats_reports_page( $main_chart_only = false ) { $timeout = 90; $user_id = JETPACK_MASTER_USER; // means send the wp.com user_id - $get = Jetpack_Client::remote_request( compact( 'url', 'method', 'timeout', 'user_id' ) ); + $get = Client::remote_request( compact( 'url', 'method', 'timeout', 'user_id' ) ); $get_code = wp_remote_retrieve_response_code( $get ); if ( is_wp_error( $get ) || ( 2 !== intval( $get_code / 100 ) && 304 !== $get_code ) || empty( $get['body'] ) ) { stats_print_wp_remote_error( $get, $url ); @@ -1326,7 +1327,7 @@ function stats_dashboard_widget_content() { $timeout = 90; $user_id = JETPACK_MASTER_USER; - $get = Jetpack_Client::remote_request( compact( 'url', 'method', 'timeout', 'user_id' ) ); + $get = Client::remote_request( compact( 'url', 'method', 'timeout', 'user_id' ) ); $get_code = wp_remote_retrieve_response_code( $get ); if ( is_wp_error( $get ) || ( 2 !== intval( $get_code / 100 ) && 304 !== $get_code ) || empty( $get['body'] ) ) { stats_print_wp_remote_error( $get, $url ); @@ -1580,7 +1581,7 @@ function stats_get_remote_csv( $url ) { $timeout = 90; $user_id = JETPACK_MASTER_USER; - $get = Jetpack_Client::remote_request( compact( 'url', 'method', 'timeout', 'user_id' ) ); + $get = Client::remote_request( compact( 'url', 'method', 'timeout', 'user_id' ) ); $get_code = wp_remote_retrieve_response_code( $get ); if ( is_wp_error( $get ) || ( 2 !== intval( $get_code / 100 ) && 304 !== $get_code ) || empty( $get['body'] ) ) { return array(); // @todo: return an error? @@ -1664,7 +1665,7 @@ function stats_get_from_restapi( $args = array(), $resource = '' ) { } // Do the dirty work. - $response = Jetpack_Client::wpcom_json_api_request_as_blog( $endpoint, $api_version, $args ); + $response = Client::wpcom_json_api_request_as_blog( $endpoint, $api_version, $args ); if ( 200 !== wp_remote_retrieve_response_code( $response ) ) { $data = is_wp_error( $response ) ? $response : new WP_Error( 'stats_error' ); } else { diff --git a/modules/videopress/class.videopress-ajax.php b/modules/videopress/class.videopress-ajax.php index e1943c0b41bd6..620605a903433 100644 --- a/modules/videopress/class.videopress-ajax.php +++ b/modules/videopress/class.videopress-ajax.php @@ -1,5 +1,7 @@ __( 'Could not obtain a VideoPress upload token. Please try again later.', 'jetpack' ) ) ); diff --git a/modules/videopress/class.videopress-edit-attachment.php b/modules/videopress/class.videopress-edit-attachment.php index be7ddfde29cd8..5d55b2c61f8b3 100644 --- a/modules/videopress/class.videopress-edit-attachment.php +++ b/modules/videopress/class.videopress-edit-attachment.php @@ -1,4 +1,7 @@ '', - 'user_id' => 0, - 'blog_id' => 0, - 'auth_location' => JETPACK_CLIENT__AUTH_LOCATION, - 'method' => 'POST', - 'timeout' => 10, - 'redirection' => 0, - 'headers' => array(), - 'stream' => false, - 'filename' => null, - 'sslverify' => true, + 'url' => '', + 'user_id' => 0, + 'blog_id' => 0, + 'auth_location' => Constants::get_constant( 'JETPACK_CLIENT__AUTH_LOCATION' ), + 'method' => 'POST', + 'timeout' => 10, + 'redirection' => 0, + 'headers' => array(), + 'stream' => false, + 'filename' => null, + 'sslverify' => true, ); $args = wp_parse_args( $args, $defaults ); $args['blog_id'] = (int) $args['blog_id']; - if ( 'header' != $args['auth_location'] ) { + if ( 'header' !== $args['auth_location'] ) { $args['auth_location'] = 'query_string'; } - $token = Jetpack_Data::get_access_token( $args['user_id'] ); - if ( !$token ) { - return new Jetpack_Error( 'missing_token' ); + $token = \Jetpack_Data::get_access_token( $args['user_id'] ); + if ( ! $token ) { + return new \WP_Error( 'missing_token' ); } $method = strtoupper( $args['method'] ); @@ -41,31 +55,36 @@ public static function remote_request( $args, $body = null ) { $timeout = intval( $args['timeout'] ); $redirection = $args['redirection']; - $stream = $args['stream']; - $filename = $args['filename']; - $sslverify = $args['sslverify']; + $stream = $args['stream']; + $filename = $args['filename']; + $sslverify = $args['sslverify']; $request = compact( 'method', 'body', 'timeout', 'redirection', 'stream', 'filename', 'sslverify' ); - @list( $token_key, $secret ) = explode( '.', $token->secret ); + @list( $token_key, $secret ) = explode( '.', $token->secret ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged if ( empty( $token ) || empty( $secret ) ) { - return new Jetpack_Error( 'malformed_token' ); + return new \WP_Error( 'malformed_token' ); } - $token_key = sprintf( '%s:%d:%d', $token_key, JETPACK__API_VERSION, $token->external_user_id ); + $token_key = sprintf( + '%s:%d:%d', + $token_key, + Constants::get_constant( 'JETPACK__API_VERSION' ), + $token->external_user_id + ); - $time_diff = (int) Jetpack_Options::get_option( 'time_diff' ); - $jetpack_signature = new Jetpack_Signature( $token->secret, $time_diff ); + $time_diff = (int) \Jetpack_Options::get_option( 'time_diff' ); + $jetpack_signature = new \Jetpack_Signature( $token->secret, $time_diff ); $timestamp = time() + $time_diff; - if( function_exists( 'wp_generate_password' ) ) { + if ( function_exists( 'wp_generate_password' ) ) { $nonce = wp_generate_password( 10, false ); } else { - $nonce = substr( sha1( rand( 0, 1000000 ) ), 0, 10); + $nonce = substr( sha1( wp_rand( 0, 1000000 ) ), 0, 10 ); } - // Kind of annoying. Maybe refactor Jetpack_Signature to handle body-hashing + // Kind of annoying. Maybe refactor Jetpack_Signature to handle body-hashing. if ( is_null( $body ) ) { $body_hash = ''; @@ -77,64 +96,67 @@ public static function remote_request( $args, $body = null ) { // We cast this to a new variable, because the array form of $body needs to be // maintained so it can be passed into the request later on in the code. if ( count( $body ) > 0 ) { - $body_to_hash = json_encode( self::_stringify_data( $body ) ); + $body_to_hash = wp_json_encode( self::_stringify_data( $body ) ); } else { $body_to_hash = ''; } } if ( ! is_string( $body_to_hash ) ) { - return new Jetpack_Error( 'invalid_body', 'Body is malformed.' ); + return new \WP_Error( 'invalid_body', 'Body is malformed.' ); } - $body_hash = Jetpack::connection()->sha1_base64( $body_to_hash ); + $body_hash = base64_encode( sha1( $body_to_hash, true ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode } $auth = array( - 'token' => $token_key, + 'token' => $token_key, 'timestamp' => $timestamp, - 'nonce' => $nonce, + 'nonce' => $nonce, 'body-hash' => $body_hash, ); if ( false !== strpos( $args['url'], 'xmlrpc.php' ) ) { $url_args = array( 'for' => 'jetpack', - 'wpcom_blog_id' => Jetpack_Options::get_option( 'id' ), + 'wpcom_blog_id' => \Jetpack_Options::get_option( 'id' ), ); } else { $url_args = array(); } - if ( 'header' != $args['auth_location'] ) { + if ( 'header' !== $args['auth_location'] ) { $url_args += $auth; } $url = add_query_arg( urlencode_deep( $url_args ), $args['url'] ); - $url = Jetpack::fix_url_for_bad_hosts( $url ); + $url = \Jetpack::fix_url_for_bad_hosts( $url ); $signature = $jetpack_signature->sign_request( $token_key, $timestamp, $nonce, $body_hash, $method, $url, $body, false ); - if ( !$signature || is_wp_error( $signature ) ) { + if ( ! $signature || is_wp_error( $signature ) ) { return $signature; } - // Send an Authorization header so various caches/proxies do the right thing + // Send an Authorization header so various caches/proxies do the right thing. $auth['signature'] = $signature; - $auth['version'] = JETPACK__VERSION; - $header_pieces = array(); + $auth['version'] = Constants::get_constant( 'JETPACK__VERSION' ); + $header_pieces = array(); foreach ( $auth as $key => $value ) { $header_pieces[] = sprintf( '%s="%s"', $key, $value ); } - $request['headers'] = array_merge( $args['headers'], array( - 'Authorization' => "X_JETPACK " . join( ' ', $header_pieces ), - ) ); + $request['headers'] = array_merge( + $args['headers'], + array( + 'Authorization' => 'X_JETPACK ' . join( ' ', $header_pieces ), + ) + ); - if ( 'header' != $args['auth_location'] ) { - $url = add_query_arg( 'signature', urlencode( $signature ), $url ); + if ( 'header' !== $args['auth_location'] ) { + $url = add_query_arg( 'signature', rawurlencode( $signature ), $url ); } - return Jetpack_Client::_wp_remote_request( $url, $request ); + return self::_wp_remote_request( $url, $request ); } /** @@ -150,6 +172,9 @@ public static function remote_request( $args, $body = null ) { * @internal * @see Jetpack::fix_url_for_bad_hosts() * + * @param String $url the request URL. + * @param Array $args request arguments. + * @param Boolean $set_fallback whether to allow flagging this request to use a fallback certficate override. * @return array|WP_Error WP HTTP response on success */ public static function _wp_remote_request( $url, $args, $set_fallback = false ) { @@ -168,26 +193,26 @@ public static function _wp_remote_request( $url, $args, $set_fallback = false ) return wp_remote_request( $url, $args ); } - $fallback = Jetpack_Options::get_option( 'fallback_no_verify_ssl_certs' ); + $fallback = \Jetpack_Options::get_option( 'fallback_no_verify_ssl_certs' ); if ( false === $fallback ) { - Jetpack_Options::update_option( 'fallback_no_verify_ssl_certs', 0 ); + \Jetpack_Options::update_option( 'fallback_no_verify_ssl_certs', 0 ); } if ( (int) $fallback ) { - // We're flagged to fallback + // We're flagged to fallback. $args['sslverify'] = false; } $response = wp_remote_request( $url, $args ); if ( - !$set_fallback // We're not allowed to set the flag on this request, so whatever happens happens - || - isset( $args['sslverify'] ) && !$args['sslverify'] // No verification - no point in doing it again - || - !is_wp_error( $response ) // Let it ride + ! $set_fallback // We're not allowed to set the flag on this request, so whatever happens happens. + || + isset( $args['sslverify'] ) && ! $args['sslverify'] // No verification - no point in doing it again. + || + ! is_wp_error( $response ) // Let it ride. ) { - Jetpack_Client::set_time_diff( $response, $set_fallback ); + self::set_time_diff( $response, $set_fallback ); return $response; } @@ -197,17 +222,17 @@ public static function _wp_remote_request( $url, $args, $set_fallback = false ) // Is it an SSL Certificate verification error? if ( - false === strpos( $message, '14090086' ) // OpenSSL SSL3 certificate error - && - false === strpos( $message, '1407E086' ) // OpenSSL SSL2 certificate error - && - false === strpos( $message, 'error setting certificate verify locations' ) // cURL CA bundle not found - && + false === strpos( $message, '14090086' ) // OpenSSL SSL3 certificate error. + && + false === strpos( $message, '1407E086' ) // OpenSSL SSL2 certificate error. + && + false === strpos( $message, 'error setting certificate verify locations' ) // cURL CA bundle not found. + && false === strpos( $message, 'Peer certificate cannot be authenticated with' ) // cURL CURLE_SSL_CACERT: CA bundle found, but not helpful - // different versions of curl have different error messages - // this string should catch them all - && - false === strpos( $message, 'Problem with the SSL CA cert' ) // cURL CURLE_SSL_CACERT_BADFILE: probably access rights + // Different versions of curl have different error messages + // this string should catch them all. + && + false === strpos( $message, 'Problem with the SSL CA cert' ) // cURL CURLE_SSL_CACERT_BADFILE: probably access rights. ) { // No, it is not. return $response; @@ -215,41 +240,49 @@ public static function _wp_remote_request( $url, $args, $set_fallback = false ) // Redo the request without SSL certificate verification. $args['sslverify'] = false; - $response = wp_remote_request( $url, $args ); + $response = wp_remote_request( $url, $args ); - if ( !is_wp_error( $response ) ) { - // The request went through this time, flag for future fallbacks - Jetpack_Options::update_option( 'fallback_no_verify_ssl_certs', time() ); - Jetpack_Client::set_time_diff( $response, $set_fallback ); + if ( ! is_wp_error( $response ) ) { + // The request went through this time, flag for future fallbacks. + \Jetpack_Options::update_option( 'fallback_no_verify_ssl_certs', time() ); + self::set_time_diff( $response, $set_fallback ); } return $response; } + /** + * Sets the time difference for correct signature computation. + * + * @param HTTP_Response $response the response object. + * @param Boolean $force_set whether to force setting the time difference. + */ public static function set_time_diff( &$response, $force_set = false ) { $code = wp_remote_retrieve_response_code( $response ); - // Only trust the Date header on some responses - if ( 200 != $code && 304 != $code && 400 != $code && 401 != $code ) { + // Only trust the Date header on some responses. + if ( 200 != $code && 304 != $code && 400 != $code && 401 != $code ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison return; } - if ( !$date = wp_remote_retrieve_header( $response, 'date' ) ) { + $date = wp_remote_retrieve_header( $response, 'date' ); + if ( ! $date ) { return; } - if ( 0 >= $time = (int) strtotime( $date ) ) { + $time = (int) strtotime( $date ); + if ( 0 >= $time ) { return; } $time_diff = $time - time(); - if ( $force_set ) { // during register - Jetpack_Options::update_option( 'time_diff', $time_diff ); - } else { // otherwise - $old_diff = Jetpack_Options::get_option( 'time_diff' ); + if ( $force_set ) { // During register. + \Jetpack_Options::update_option( 'time_diff', $time_diff ); + } else { // Otherwise. + $old_diff = \Jetpack_Options::get_option( 'time_diff' ); if ( false === $old_diff || abs( $time_diff - (int) $old_diff ) > 10 ) { - Jetpack_Options::update_option( 'time_diff', $time_diff ); + \Jetpack_Options::update_option( 'time_diff', $time_diff ); } } } @@ -265,24 +298,40 @@ public static function set_time_diff( &$response, $force_set = false ) { * * @return array|WP_Error $response Response data, else {@see WP_Error} on failure. */ - public static function wpcom_json_api_request_as_user( $path, $version = '2', $args = array(), $body = null, $base_api_path = 'wpcom' ) { + public static function wpcom_json_api_request_as_user( + $path, + $version = '2', + $args = array(), + $body = null, + $base_api_path = 'wpcom' + ) { $base_api_path = trim( $base_api_path, '/' ); $version = ltrim( $version, 'v' ); $path = ltrim( $path, '/' ); - $args = array_intersect_key( $args, array( - 'headers' => 'array', - 'method' => 'string', - 'timeout' => 'int', - 'redirection' => 'int', - 'stream' => 'boolean', - 'filename' => 'string', - 'sslverify' => 'boolean', - ) ); + $args = array_intersect_key( + $args, + array( + 'headers' => 'array', + 'method' => 'string', + 'timeout' => 'int', + 'redirection' => 'int', + 'stream' => 'boolean', + 'filename' => 'string', + 'sslverify' => 'boolean', + ) + ); $args['user_id'] = get_current_user_id(); $args['method'] = isset( $args['method'] ) ? strtoupper( $args['method'] ) : 'GET'; - $args['url'] = sprintf( '%s://%s/%s/v%s/%s', self::protocol(), JETPACK__WPCOM_JSON_API_HOST, $base_api_path, $version, $path ); + $args['url'] = sprintf( + '%s://%s/%s/v%s/%s', + self::protocol(), + Constants::get_constant( 'JETPACK__WPCOM_JSON_API_HOST' ), + $base_api_path, + $version, + $path + ); if ( isset( $body ) && ! isset( $args['headers'] ) && in_array( $args['method'], array( 'POST', 'PUT', 'PATCH' ), true ) ) { $args['headers'] = array( 'Content-Type' => 'application/json' ); @@ -298,39 +347,58 @@ public static function wpcom_json_api_request_as_user( $path, $version = '2', $a /** * Query the WordPress.com REST API using the blog token * - * @param string $path - * @param string $version - * @param array $args - * @param string $body - * @param string $base_api_path - * @return array|WP_Error $response Data. + * @param String $path The API endpoint relative path. + * @param String $version The API version. + * @param Array $args Request arguments. + * @param String $body Request body. + * @param String $base_api_path (optional) the API base path override, defaults to 'rest'. + * @return Array|WP_Error $response Data. */ - static function wpcom_json_api_request_as_blog( $path, $version = self::WPCOM_JSON_API_VERSION, $args = array(), $body = null, $base_api_path = 'rest' ) { - $filtered_args = array_intersect_key( $args, array( - 'headers' => 'array', - 'method' => 'string', - 'timeout' => 'int', - 'redirection' => 'int', - 'stream' => 'boolean', - 'filename' => 'string', - 'sslverify' => 'boolean', - ) ); - - // unprecedingslashit + public static function wpcom_json_api_request_as_blog( + $path, + $version = self::WPCOM_JSON_API_VERSION, + $args = array(), + $body = null, + $base_api_path = 'rest' + ) { + $filtered_args = array_intersect_key( + $args, + array( + 'headers' => 'array', + 'method' => 'string', + 'timeout' => 'int', + 'redirection' => 'int', + 'stream' => 'boolean', + 'filename' => 'string', + 'sslverify' => 'boolean', + ) + ); + + // unprecedingslashit. $_path = preg_replace( '/^\//', '', $path ); - // Use GET by default whereas `remote_request` uses POST + // Use GET by default whereas `remote_request` uses POST. $request_method = ( isset( $filtered_args['method'] ) ) ? $filtered_args['method'] : 'GET'; - $url = sprintf( '%s://%s/%s/v%s/%s', self::protocol(), JETPACK__WPCOM_JSON_API_HOST, $base_api_path, $version, $_path ); + $url = sprintf( + '%s://%s/%s/v%s/%s', + self::protocol(), + Constants::get_constant( 'JETPACK__WPCOM_JSON_API_HOST' ), + $base_api_path, + $version, + $_path + ); - $validated_args = array_merge( $filtered_args, array( - 'url' => $url, - 'blog_id' => (int) Jetpack_Options::get_option( 'id' ), - 'method' => $request_method, - ) ); + $validated_args = array_merge( + $filtered_args, + array( + 'url' => $url, + 'blog_id' => (int) \Jetpack_Options::get_option( 'id' ), + 'method' => $request_method, + ) + ); - return Jetpack_Client::remote_request( $validated_args, $body ); + return self::remote_request( $validated_args, $body ); } /** @@ -338,7 +406,7 @@ static function wpcom_json_api_request_as_blog( $path, $version = self::WPCOM_JS * make sure that body hashes are made ith the string version, which is what will be seen after a * server pulls up the data in the $_POST array. * - * @param array|mixed $data + * @param Array|Mixed $data the data that needs to be stringified. * * @return array|string */ @@ -346,7 +414,7 @@ public static function _stringify_data( $data ) { // Booleans are special, lets just makes them and explicit 1/0 instead of the 0 being an empty string. if ( is_bool( $data ) ) { - return $data ? "1" : "0"; + return $data ? '1' : '0'; } // Cast objects into arrays. @@ -356,7 +424,7 @@ public static function _stringify_data( $data ) { // Non arrays at this point should be just converted to strings. if ( ! is_array( $data ) ) { - return (string)$data; + return (string) $data; } foreach ( $data as $key => &$value ) { diff --git a/packages/jitm/src/JITM.php b/packages/jitm/src/JITM.php index 16b74d6bd6b46..41ddad1a3dc15 100644 --- a/packages/jitm/src/JITM.php +++ b/packages/jitm/src/JITM.php @@ -4,6 +4,7 @@ use Automattic\Jetpack\Asset_Tools; use Automattic\Jetpack\Connection\Manager as Jetpack_Connection; +use Automattic\Jetpack\Connection\Client; use Automattic\Jetpack\Assets\Logo as Jetpack_Logo; use Automattic\Jetpack\Tracking; @@ -287,8 +288,6 @@ function get_messages( $message_path, $query ) { return array(); } - require_once JETPACK__PLUGIN_DIR . 'class.jetpack-client.php'; - $site_id = \Jetpack_Options::get_option( 'id' ); // build our jitm request @@ -322,7 +321,7 @@ function get_messages( $message_path, $query ) { // otherwise, ask again if ( ! $from_cache ) { - $wpcom_response = \Jetpack_Client::wpcom_json_api_request_as_blog( + $wpcom_response = Client::wpcom_json_api_request_as_blog( $path, '2', array(