function query()
 {
     $args = func_get_args();
     $method = array_shift($args);
     $request = new IXR_Request($method, $args);
     $xml = trim($request->getXml());
     $response = Jetpack_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()));
         return false;
     }
     if (!$response) {
         $this->error = new IXR_Error(-10520, 'Jetpack: Unknown Error');
         return false;
     }
     if (200 != wp_remote_retrieve_response_code($response)) {
         $this->error = new IXR_Error(-32300, 'transport error - HTTP status code was not 200');
         return false;
     }
     $content = wp_remote_retrieve_body($response);
     // Now parse what we've got back
     $this->message = new IXR_Message($content);
     if (!$this->message->parse()) {
         // XML error
         $this->error = new IXR_Error(-32700, 'parse error. not well formed');
         return false;
     }
     // Is the message a fault?
     if ($this->message->messageType == 'fault') {
         $this->error = new IXR_Error($this->message->faultCode, $this->message->faultString);
         return false;
     }
     // Message must be OK
     return true;
 }
 protected static function download_wpcom_theme_to_file($theme)
 {
     $wpcom_theme_slug = preg_replace('/-wpcom$/', '', $theme);
     $file = wp_tempnam('theme');
     if (!$file) {
         return new WP_Error('problem_creating_theme_file', __('Problem creating file for theme download', 'jetpack'));
     }
     $url = "themes/download/{$theme}.zip";
     $args = array('stream' => true, 'filename' => $file);
     $result = Jetpack_Client::wpcom_json_api_request_as_blog($url, '1.1', $args);
     $response = $result['response'];
     if ($response['code'] !== 200) {
         unlink($file);
         return new WP_Error('problem_fetching_theme', __('Problem downloading theme', 'jetpack'));
     }
     return $file;
 }
 /**
  * Ajax method that is used by the VideoPress uploader to get a token to upload a file to the wpcom api.
  *
  * @return void
  */
 public function wp_ajax_videopress_get_upload_token()
 {
     $options = VideoPress_Options::get_options();
     $args = array('method' => 'POST');
     $endpoint = "sites/{$options['shadow_blog_id']}/media/token";
     $result = Jetpack_Client::wpcom_json_api_request_as_blog($endpoint, Jetpack_Client::WPCOM_JSON_API_VERSION, $args);
     if (is_wp_error($result)) {
         wp_send_json_error(array('message' => __('Could not obtain a VideoPress upload token. Please try again later.', 'jetpack')));
         return;
     }
     $response = json_decode($result['body'], true);
     if (empty($response['upload_token'])) {
         wp_send_json_error(array('message' => __('Could not obtain a VideoPress upload token. Please try again later.', 'jetpack')));
         return;
     }
     $title = sanitize_title(basename($_POST['filename']));
     $response['upload_action_url'] = videopress_make_media_upload_path($options['shadow_blog_id']);
     $response['upload_media_id'] = videopress_create_new_media_item($title);
     wp_send_json_success($response);
 }
 /**
  * @return bool|WP_Error
  */
 public static function register()
 {
     add_action('pre_update_jetpack_option_register', array('Jetpack_Options', 'delete_option'));
     $secrets = Jetpack::init()->generate_secrets();
     Jetpack_Options::update_option('register', $secrets[0] . ':' . $secrets[1] . ':' . $secrets[2]);
     @(list($secret_1, $secret_2, $secret_eol) = explode(':', Jetpack_Options::get_option('register')));
     if (empty($secret_1) || empty($secret_2) || empty($secret_eol) || $secret_eol < time()) {
         return new Jetpack_Error('missing_secrets');
     }
     $timeout = Jetpack::init()->get_remote_query_timeout_limit();
     $gmt_offset = get_option('gmt_offset');
     if (!$gmt_offset) {
         $gmt_offset = 0;
     }
     $stats_options = get_option('stats_options');
     $stats_id = isset($stats_options['blog_id']) ? $stats_options['blog_id'] : null;
     $args = array('method' => 'POST', 'body' => array('siteurl' => site_url(), 'home' => home_url(), 'gmt_offset' => $gmt_offset, 'timezone_string' => (string) get_option('timezone_string'), 'site_name' => (string) get_option('blogname'), 'secret_1' => $secret_1, 'secret_2' => $secret_2, 'site_lang' => get_locale(), 'timeout' => $timeout, 'stats_id' => $stats_id), 'headers' => array('Accept' => 'application/json'), 'timeout' => $timeout);
     $response = Jetpack_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
     $valid_response = Jetpack::init()->validate_remote_register_response($response);
     if (is_wp_error($valid_response) || !$valid_response) {
         return $valid_response;
     }
     // Grab the response values to work with
     $code = wp_remote_retrieve_response_code($response);
     $entity = wp_remote_retrieve_body($response);
     if ($entity) {
         $json = json_decode($entity);
     } else {
         $json = false;
     }
     if (empty($json->jetpack_secret) || !is_string($json->jetpack_secret)) {
         return new Jetpack_Error('jetpack_secret', '', $code);
     }
     if (isset($json->jetpack_public)) {
         $jetpack_public = (int) $json->jetpack_public;
     } else {
         $jetpack_public = false;
     }
     Jetpack_Options::update_options(array('id' => (int) $json->jetpack_id, 'blog_token' => (string) $json->jetpack_secret, 'public' => $jetpack_public));
     return true;
 }
 /**
  * @return bool|WP_Error
  */
 public static function register()
 {
     Jetpack_Options::update_option('register', wp_generate_password(32, false) . ':' . wp_generate_password(32, false) . ':' . (time() + 600));
     @(list($secret_1, $secret_2, $secret_eol) = explode(':', Jetpack_Options::get_option('register')));
     if (empty($secret_1) || empty($secret_2) || empty($secret_eol) || $secret_eol < time()) {
         return new Jetpack_Error('missing_secrets');
     }
     $timeout = (int) ini_get('max_execution_time');
     if (!$timeout) {
         $timeout = 30;
     }
     $timeout = intval($timeout / 2);
     $gmt_offset = get_option('gmt_offset');
     if (!$gmt_offset) {
         $gmt_offset = 0;
     }
     $stats_options = get_option('stats_options');
     $stats_id = isset($stats_options['blog_id']) ? $stats_options['blog_id'] : null;
     $args = array('method' => 'POST', 'body' => array('siteurl' => site_url(), 'home' => home_url(), 'gmt_offset' => $gmt_offset, 'timezone_string' => (string) get_option('timezone_string'), 'site_name' => (string) get_option('blogname'), 'secret_1' => $secret_1, 'secret_2' => $secret_2, 'site_lang' => get_locale(), 'timeout' => $timeout, 'stats_id' => $stats_id), 'headers' => array('Accept' => 'application/json'), 'timeout' => $timeout);
     $response = Jetpack_Client::_wp_remote_request(Jetpack::fix_url_for_bad_hosts(Jetpack::api_url('register')), $args, true);
     if (is_wp_error($response)) {
         return new Jetpack_Error('register_http_request_failed', $response->get_error_message());
     }
     $code = wp_remote_retrieve_response_code($response);
     $entity = wp_remote_retrieve_body($response);
     if ($entity) {
         $json = json_decode($entity);
     } else {
         $json = false;
     }
     $code_type = intval($code / 100);
     if (5 == $code_type) {
         return new Jetpack_Error('wpcom_5??', sprintf(__('Error Details: %s', 'jetpack'), $code), $code);
     } elseif (408 == $code) {
         return new Jetpack_Error('wpcom_408', sprintf(__('Error Details: %s', 'jetpack'), $code), $code);
     } elseif (!empty($json->error)) {
         $error_description = isset($json->error_description) ? sprintf(__('Error Details: %s', 'jetpack'), (string) $json->error_description) : '';
         return new Jetpack_Error((string) $json->error, $error_description, $code);
     } elseif (200 != $code) {
         return new Jetpack_Error('wpcom_bad_response', sprintf(__('Error Details: %s', 'jetpack'), $code), $code);
     }
     // Jetpack ID error block
     if (empty($json->jetpack_id)) {
         return new Jetpack_Error('jetpack_id', sprintf(__('Error Details: Jetpack ID is empty. Do not publicly post this error message! %s', 'jetpack'), $entity), $entity);
     } elseif (!is_scalar($json->jetpack_id)) {
         return new Jetpack_Error('jetpack_id', sprintf(__('Error Details: Jetpack ID is not a scalar. Do not publicly post this error message! %s', 'jetpack'), $entity), $entity);
     } elseif (preg_match('/[^0-9]/', $json->jetpack_id)) {
         return new Jetpack_Error('jetpack_id', sprintf(__('Error Details: Jetpack ID begins with a numeral. Do not publicly post this error message! %s', 'jetpack'), $entity), $entity);
     }
     if (empty($json->jetpack_secret) || !is_string($json->jetpack_secret)) {
         return new Jetpack_Error('jetpack_secret', '', $code);
     }
     if (isset($json->jetpack_public)) {
         $jetpack_public = (int) $json->jetpack_public;
     } else {
         $jetpack_public = false;
     }
     Jetpack_Options::update_options(array('id' => (int) $json->jetpack_id, 'blog_token' => (string) $json->jetpack_secret, 'public' => $jetpack_public));
     return true;
 }
 /**
  * @return bool|WP_Error
  */
 public static function register()
 {
     add_action('pre_update_jetpack_option_register', array('Jetpack_Options', 'delete_option'));
     $secrets = Jetpack::init()->generate_secrets('register');
     @(list($secret_1, $secret_2, $secret_eol) = explode(':', $secrets));
     if (empty($secret_1) || empty($secret_2) || empty($secret_eol) || $secret_eol < time()) {
         return new Jetpack_Error('missing_secrets');
     }
     $timeout = Jetpack::init()->get_remote_query_timeout_limit();
     $gmt_offset = get_option('gmt_offset');
     if (!$gmt_offset) {
         $gmt_offset = 0;
     }
     $stats_options = get_option('stats_options');
     $stats_id = isset($stats_options['blog_id']) ? $stats_options['blog_id'] : null;
     $args = array('method' => 'POST', 'body' => array('siteurl' => site_url(), 'home' => home_url(), 'gmt_offset' => $gmt_offset, 'timezone_string' => (string) get_option('timezone_string'), 'site_name' => (string) get_option('blogname'), 'secret_1' => $secret_1, 'secret_2' => $secret_2, 'site_lang' => get_locale(), 'timeout' => $timeout, 'stats_id' => $stats_id, 'state' => get_current_user_id()), 'headers' => array('Accept' => 'application/json'), 'timeout' => $timeout);
     $response = Jetpack_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
     $valid_response = Jetpack::init()->validate_remote_register_response($response);
     if (is_wp_error($valid_response) || !$valid_response) {
         return $valid_response;
     }
     // Grab the response values to work with
     $code = wp_remote_retrieve_response_code($response);
     $entity = wp_remote_retrieve_body($response);
     if ($entity) {
         $json = json_decode($entity);
     } else {
         $json = false;
     }
     if (empty($json->jetpack_secret) || !is_string($json->jetpack_secret)) {
         return new Jetpack_Error('jetpack_secret', '', $code);
     }
     if (isset($json->jetpack_public)) {
         $jetpack_public = (int) $json->jetpack_public;
     } else {
         $jetpack_public = false;
     }
     Jetpack_Options::update_options(array('id' => (int) $json->jetpack_id, 'blog_token' => (string) $json->jetpack_secret, 'public' => $jetpack_public));
     /**
      * Fires when a site is registered on WordPress.com.
      *
      * @since 3.7.0
      *
      * @param int $json->jetpack_id Jetpack Blog ID.
      * @param string $json->jetpack_secret Jetpack Blog Token.
      * @param int|bool $jetpack_public Is the site public.
      */
     do_action('jetpack_site_registered', $json->jetpack_id, $json->jetpack_secret, $jetpack_public);
     // Initialize Jump Start for the first and only time.
     if (!Jetpack_Options::get_option('jumpstart')) {
         Jetpack_Options::update_option('jumpstart', 'new_connection');
         $jetpack = Jetpack::init();
         $jetpack->stat('jumpstart', 'unique-views');
         $jetpack->do_stats('server_side');
     }
     return true;
 }
 /**
  * @return object|WP_Error
  */
 function get_token($data)
 {
     $jetpack = Jetpack::init();
     $role = $jetpack->translate_current_user_to_role();
     if (!$role) {
         return new Jetpack_Error('role', __('An administrator for this blog must set up the Jetpack connection.', 'jetpack'));
     }
     $client_secret = Jetpack_Data::get_access_token(0);
     if (!$client_secret) {
         return new Jetpack_Error('client_secret', __('You need to register your Jetpack before connecting it.', 'jetpack'));
     }
     $body = array('client_id' => Jetpack::get_option('id'), 'client_secret' => $client_secret->secret, 'grant_type' => 'authorization_code', 'code' => $data['code'], 'redirect_uri' => add_query_arg(array('action' => 'authorize', '_wpnonce' => wp_create_nonce("jetpack-authorize_{$role}")), menu_page_url('jetpack', false)));
     $args = array('method' => 'POST', 'body' => $body, 'headers' => array('Accept' => 'application/json'));
     $response = Jetpack_Client::_wp_remote_request(Jetpack::fix_url_for_bad_hosts(Jetpack::api_url('token'), $args), $args);
     if (is_wp_error($response)) {
         return new Jetpack_Error('token_http_request_failed', $response->get_error_message());
     }
     $code = wp_remote_retrieve_response_code($response);
     $entity = wp_remote_retrieve_body($response);
     if ($entity) {
         $json = json_decode($entity);
     } else {
         $json = false;
     }
     if (200 != $code || !empty($json->error)) {
         if (empty($json->error)) {
             return new Jetpack_Error('unknown', '', $code);
         }
         $error_description = isset($json->error_description) ? sprintf(__('Error Details: %s', 'jetpack'), (string) $json->error_description) : '';
         return new Jetpack_Error((string) $json->error, $error_description, $code);
     }
     if (empty($json->access_token) || !is_scalar($json->access_token)) {
         return new Jetpack_Error('access_token', '', $code);
     }
     if (empty($json->token_type) || 'X_JETPACK' != strtoupper($json->token_type)) {
         return new Jetpack_Error('token_type', '', $code);
     }
     if (empty($json->scope)) {
         return new Jetpack_Error('scope', 'No Scope', $code);
     }
     @(list($role, $hmac) = explode(':', $json->scope));
     if (empty($role) || empty($hmac)) {
         return new Jetpack_Error('scope', 'Malformed Scope', $code);
     }
     if ($jetpack->sign_role($role) !== $json->scope) {
         return new Jetpack_Error('scope', 'Invalid Scope', $code);
     }
     if (!($cap = $jetpack->translate_role_to_cap($role))) {
         return new Jetpack_Error('scope', 'No Cap', $code);
     }
     if (!current_user_can($cap)) {
         return new Jetpack_Error('scope', 'current_user_cannot', $code);
     }
     return (string) $json->access_token;
 }
Example #8
0
/**
 * Fetches stats data from the REST API.  Caches locally for 5 minutes.
 *
 * @link: https://developer.wordpress.com/docs/api/1.1/get/sites/%24site/stats/
 *
 * @param  array|string   $args     The args that are passed to the endpoint
 * @param  string         $resource Optional sub-endpoint following /stats/
 * @return array|WP_Error
 */
function stats_get_from_restapi($args = array(), $resource = '')
{
    $endpoint = jetpack_stats_api_path($resource);
    $api_version = '1.1';
    $args = wp_parse_args($args, array());
    $cache_key = md5(implode('|', array($endpoint, $api_version, serialize($args))));
    // Get cache
    $stats_cache = Jetpack_Options::get_option('restapi_stats_cache', array());
    if (!is_array($stats_cache)) {
        $stats_cache = array();
    }
    // Return or expire this key
    if (isset($stats_cache[$cache_key])) {
        $time = key($stats_cache[$cache_key]);
        if (time() - $time < 5 * MINUTE_IN_SECONDS) {
            $cached_stats = $stats_cache[$cache_key][$time];
            $cached_stats = (object) array_merge(array('cached_at' => $time), (array) $cached_stats);
            return $cached_stats;
        }
        unset($stats_cache[$cache_key]);
    }
    // Do the dirty work.
    $response = Jetpack_Client::wpcom_json_api_request_as_blog($endpoint, $api_version, $args);
    if (200 !== wp_remote_retrieve_response_code($response)) {
        // If bad, just return it, don't cache.
        return $response;
    }
    $data = json_decode(wp_remote_retrieve_body($response));
    // Expire old keys
    foreach ($stats_cache as $k => $cache) {
        if (!is_array($cache) || 5 * MINUTE_IN_SECONDS < time() - key($cache)) {
            unset($stats_cache[$k]);
        }
    }
    // Set cache
    $stats_cache[$cache_key] = array(time() => $data);
    Jetpack_Options::update_option('restapi_stats_cache', $stats_cache, false);
    return $data;
}
 /**
  * Wrapper for wp_remote_request().  Turns off SSL verification for certain SSL errors.
  * This is lame, but many, many, many hosts have misconfigured SSL.
  *
  * When Jetpack is registered, the jetpack_fallback_no_verify_ssl_certs option is set to the current time if:
  * 1. a certificate error is found AND
  * 2. not verifying the certificate works around the problem.
  *
  * The option is checked on each request.
  *
  * @internal
  * @see Jetpack::fix_url_for_bad_hosts()
  *
  * @return array|WP_Error WP HTTP response on success
  */
 public static function _wp_remote_request($url, $args, $set_fallback = false)
 {
     $fallback = Jetpack_Options::get_option('fallback_no_verify_ssl_certs');
     if (false === $fallback) {
         Jetpack_Options::update_option('fallback_no_verify_ssl_certs', 0);
     }
     if ((int) $fallback) {
         // We're flagged to fallback
         $args['sslverify'] = false;
     }
     $response = wp_remote_request($url, $args);
     if (!$set_fallback || isset($args['sslverify']) && !$args['sslverify'] || !is_wp_error($response)) {
         Jetpack_Client::set_time_diff($response, $set_fallback);
         return $response;
     }
     // At this point, we're not flagged to fallback and we are allowed to set the flag on this request.
     $message = $response->get_error_message();
     // Is it an SSL Certificate verification error?
     if (false === strpos($message, '14090086') && false === strpos($message, '1407E086') && false === strpos($message, 'error setting certificate verify locations') && false === strpos($message, 'Peer certificate cannot be authenticated with') && false === strpos($message, 'Problem with the SSL CA cert')) {
         // No, it is not.
         return $response;
     }
     // Redo the request without SSL certificate verification.
     $args['sslverify'] = false;
     $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);
     }
     return $response;
 }
 /**
  * Registers a subsite with the Jetpack servers
  *
  * @since 2.9
  * @todo  Break apart into easier to manage chunks that can be unit tested
  * @see   Jetpack_Network::jetpack_sites_list();
  */
 public function do_subsiteregister($site_id = null)
 {
     if (!current_user_can('jetpack_disconnect')) {
         return;
     }
     $jp = Jetpack::init();
     // Figure out what site we are working on
     $site_id = is_null($site_id) ? $_GET['site_id'] : $site_id;
     // Build secrets to sent to wpcom for verification
     $secrets = $jp->generate_secrets();
     // Remote query timeout limit
     $timeout = $jp->get_remote_query_timeout_limit();
     // The blog id on WordPress.com of the primary network site
     $network_wpcom_blog_id = Jetpack_Options::get_option('id');
     /*
      * Here we need to switch to the subsite
      * For the registration process we really only hijack how it
      * works for an individual site and pass in some extra data here
      */
     switch_to_blog($site_id);
     // Save the secrets in the subsite so when the wpcom server does a pingback it
     // will be able to validate the connection
     Jetpack_Options::update_option('register', $secrets[0] . ':' . $secrets[1] . ':' . $secrets[2]);
     // Gra info for gmt offset
     $gmt_offset = get_option('gmt_offset');
     if (!$gmt_offset) {
         $gmt_offset = 0;
     }
     /*
      * Get the stats_option option from the db.
      * It looks like the server strips this out so maybe it is not necessary?
      * Does it match the Jetpack site with the old stats plugin id?
      *
      * @todo Find out if sending the stats_id is necessary
      */
     $stat_options = get_option('stats_options');
     $stat_id = $stat_options = isset($stats_options['blog_id']) ? $stats_options['blog_id'] : null;
     $args = array('method' => 'POST', 'body' => array('network_url' => $this->get_url('network_admin_page'), 'network_wpcom_blog_id' => $network_wpcom_blog_id, 'siteurl' => site_url(), 'home' => home_url(), 'gmt_offset' => $gmt_offset, 'timezone_string' => (string) get_option('timezone_string'), 'site_name' => (string) get_option('blogname'), 'secret_1' => $secrets[0], 'secret_2' => $secrets[1], 'site_lang' => get_locale(), 'timeout' => $timeout, 'stats_id' => $stat_id, 'user_id' => get_current_user_id()), 'headers' => array('Accept' => 'application/json'), 'timeout' => $timeout);
     // Attempt to retrieve shadow blog details
     $response = Jetpack_Client::_wp_remote_request(Jetpack::fix_url_for_bad_hosts(Jetpack::api_url('subsiteregister')), $args, true);
     /*
      * $response should either be invalid or contain:
      * - jetpack_id	=> id
      * - jetpack_secret => blog_token
      * - jetpack_public
      *
      * Store the wpcom site details
      */
     $valid_response = $jp->validate_remote_register_response($response);
     if (is_wp_error($valid_response) || !$valid_response) {
         restore_current_blog();
         return $valid_response;
     }
     // Grab the response values to work with
     $code = wp_remote_retrieve_response_code($response);
     $entity = wp_remote_retrieve_body($response);
     if ($entity) {
         $json = json_decode($entity);
     } else {
         $json = false;
     }
     if (empty($json->jetpack_secret) || !is_string($json->jetpack_secret)) {
         restore_current_blog();
         return new Jetpack_Error('jetpack_secret', '', $code);
     }
     if (isset($json->jetpack_public)) {
         $jetpack_public = (int) $json->jetpack_public;
     } else {
         $jetpack_public = false;
     }
     Jetpack_Options::update_options(array('id' => (int) $json->jetpack_id, 'blog_token' => (string) $json->jetpack_secret, 'public' => $jetpack_public));
     /*
      * Update the subsiteregister method on wpcom so that it also sends back the
      * token in this same request
      */
     $is_master_user = !Jetpack::is_active();
     Jetpack::update_user_token(get_current_user_id(), sprintf('%s.%d', $json->token->secret, get_current_user_id()), $is_master_user);
     Jetpack::activate_default_modules();
     restore_current_blog();
 }
Example #11
0
function stats_get_remote_csv($url)
{
    $method = 'GET';
    $timeout = 90;
    $user_id = JETPACK_MASTER_USER;
    $get = Jetpack_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?
    } else {
        return stats_str_getcsv($get['body']);
    }
}
 /**
  * Query the WordPress.com REST API using the blog token
  *
  * @param string  $path
  * @param string  $version
  * @param array   $args
  * @param string  $body
  * @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)
 {
     $filtered_args = array_intersect_key($args, array('method' => 'string', 'timeout' => 'int', 'redirection' => 'int'));
     /**
      * Determines whether Jetpack can send outbound https requests to the WPCOM api.
      *
      * @since 3.6.0
      *
      * @param bool $proto Defaults to true.
      */
     $proto = apply_filters('jetpack_can_make_outbound_https', true) ? 'https' : 'http';
     // unprecedingslashit
     $_path = preg_replace('/^\\//', '', $path);
     // Use GET by default whereas `remote_request` uses POST
     if (isset($filtered_args['method']) && strtoupper($filtered_args['method'] === 'POST')) {
         $request_method = 'POST';
     } else {
         $request_method = 'GET';
     }
     $validated_args = array_merge($filtered_args, array('url' => sprintf('%s://%s/rest/v%s/%s', $proto, JETPACK__WPCOM_JSON_API_HOST, $version, $_path), 'blog_id' => (int) Jetpack_Options::get_option('id'), 'method' => $request_method));
     return Jetpack_Client::remote_request($validated_args, $body);
 }
 /**
  * Get site data, including for example, the site's current plan.
  *
  * @since 4.3.0
  *
  * @return array Array of Jetpack modules.
  */
 public static function get_site_data()
 {
     if ($site_id = Jetpack_Options::get_option('id')) {
         $response = Jetpack_Client::wpcom_json_api_request_as_blog(sprintf('/sites/%d', $site_id), '1.1');
         if (200 !== wp_remote_retrieve_response_code($response)) {
             return new WP_Error('site_data_fetch_failed', esc_html__('Failed fetching site data. Try again later.', 'jetpack'), array('status' => 400));
         }
         return rest_ensure_response(array('code' => 'success', 'message' => esc_html__('Site data correctly received.', 'jetpack'), 'data' => wp_remote_retrieve_body($response)));
     }
     return new WP_Error('site_id_missing', esc_html__('The ID of this site does not exist.', 'jetpack'), array('status' => 404));
 }
 /**
  * @param array $post
  * @param array|null $attachment
  *
  * @return array
  */
 public function save_fields($post, $attachment = null)
 {
     if ($attachment === null && isset($_POST['attachment'])) {
         $attachment = $_POST['attachment'];
     }
     if (!isset($attachment['is_videopress_attachment']) || $attachment['is_videopress_attachment'] !== 'yes') {
         return $post;
     }
     $post_id = absint($post['ID']);
     $meta = wp_get_attachment_metadata($post_id);
     // If this has not been processed by videopress, we can skip the rest.
     if (!isset($meta['videopress'])) {
         return $post;
     }
     $values = array();
     // Add the video title & description in, so that we save it properly.
     if (isset($_POST['post_title'])) {
         $values['title'] = trim(strip_tags($_POST['post_title']));
     }
     if (isset($_POST['post_excerpt'])) {
         $values['description'] = trim(strip_tags($_POST['post_excerpt']));
     }
     if (isset($attachment['rating'])) {
         $rating = $attachment['rating'];
         if (!empty($rating) && in_array($rating, array('G', 'PG-13', 'R-17', 'X-18'))) {
             $values['rating'] = $rating;
         }
     }
     // We set a default here, as if it isn't selected, then we'll turn it off.
     $values['display_embed'] = 0;
     if (isset($attachment['display_embed'])) {
         $display_embed = $attachment['display_embed'];
         $values['display_embed'] = 'on' === $display_embed ? 1 : 0;
     }
     $args = array('method' => 'POST');
     $endpoint = "videos/{$meta['videopress']['guid']}";
     $result = Jetpack_Client::wpcom_json_api_request_as_blog($endpoint, Jetpack_Client::WPCOM_JSON_API_VERSION, $args, $values);
     if (is_wp_error($result)) {
         $post['errors']['videopress']['errors'][] = __('There was an issue saving your updates to the VideoPress service. Please try again later.', 'jetpack');
         return $post;
     }
     if (isset($values['display_embed'])) {
         $meta['videopress']['display_embed'] = $values['display_embed'];
     }
     if (isset($values['rating'])) {
         $meta['videopress']['rating'] = $values['rating'];
     }
     wp_update_attachment_metadata($post_id, $meta);
     $response = json_decode($result['body'], true);
     if ('true' !== $response) {
         return $post;
     }
     return $post;
 }
 /**
  * Get site data, including for example, the site's current plan.
  *
  * @since 4.3.0
  *
  * @return array Array of Jetpack modules.
  */
 public static function get_site_data()
 {
     if ($site_id = Jetpack_Options::get_option('id')) {
         $response = Jetpack_Client::wpcom_json_api_request_as_blog(sprintf('/sites/%d', $site_id), '1.1');
         if (200 !== wp_remote_retrieve_response_code($response)) {
             return new WP_Error('site_data_fetch_failed', esc_html__('Failed fetching site data. Try again later.', 'jetpack'), array('status' => 400));
         }
         // Save plan details in the database for future use without API calls
         $results = json_decode($response['body'], true);
         if (is_array($results) && isset($results['plan'])) {
             update_option('jetpack_active_plan', $results['plan']);
         }
         return rest_ensure_response(array('code' => 'success', 'message' => esc_html__('Site data correctly received.', 'jetpack'), 'data' => wp_remote_retrieve_body($response)));
     }
     return new WP_Error('site_id_missing', esc_html__('The ID of this site does not exist.', 'jetpack'), array('status' => 404));
 }