load_xml_rpc_client() public static method

Loads the Jetpack XML-RPC client
public static load_xml_rpc_client ( )
    /**
     * Declare the Jetpack REST API endpoints.
     *
     * @since 4.3.0
     */
    public static function register_endpoints()
    {
        // Load API endpoint base classes
        require_once JETPACK__PLUGIN_DIR . '_inc/lib/core-api/class.jetpack-core-api-xmlrpc-consumer-endpoint.php';
        // Load API endpoints
        require_once JETPACK__PLUGIN_DIR . '_inc/lib/core-api/class.jetpack-core-api-module-endpoints.php';
        self::$user_permissions_error_msg = esc_html__('You do not have the correct user permissions to perform this action.
			Please contact your site admin if you think this is a mistake.', 'jetpack');
        self::$stats_roles = array('administrator', 'editor', 'author', 'contributor', 'subscriber');
        // Get current connection status of Jetpack
        register_rest_route('jetpack/v4', '/connection', array('methods' => WP_REST_Server::READABLE, 'callback' => __CLASS__ . '::jetpack_connection_status'));
        // Fetches a fresh connect URL
        register_rest_route('jetpack/v4', '/connection/url', array('methods' => WP_REST_Server::READABLE, 'callback' => __CLASS__ . '::build_connect_url', 'permission_callback' => __CLASS__ . '::connect_url_permission_callback'));
        // Get current user connection data
        register_rest_route('jetpack/v4', '/connection/data', array('methods' => WP_REST_Server::READABLE, 'callback' => __CLASS__ . '::get_user_connection_data', 'permission_callback' => __CLASS__ . '::get_user_connection_data_permission_callback'));
        // Disconnect site from WordPress.com servers
        register_rest_route('jetpack/v4', '/connection', array('methods' => WP_REST_Server::EDITABLE, 'callback' => __CLASS__ . '::disconnect_site', 'permission_callback' => __CLASS__ . '::disconnect_site_permission_callback'));
        // Disconnect/unlink user from WordPress.com servers
        register_rest_route('jetpack/v4', '/connection/user', array('methods' => WP_REST_Server::EDITABLE, 'callback' => __CLASS__ . '::unlink_user', 'permission_callback' => __CLASS__ . '::unlink_user_permission_callback'));
        // Get current site data
        register_rest_route('jetpack/v4', '/site', array('methods' => WP_REST_Server::READABLE, 'callback' => __CLASS__ . '::get_site_data', 'permission_callback' => __CLASS__ . '::view_admin_page_permission_check'));
        // Confirm that a site in identity crisis should be in staging mode
        register_rest_route('jetpack/v4', '/identity-crisis/confirm-safe-mode', array('methods' => WP_REST_Server::EDITABLE, 'callback' => __CLASS__ . '::confirm_safe_mode', 'permission_callback' => __CLASS__ . '::identity_crisis_mitigation_permission_check'));
        // IDC resolve: create an entirely new shadow site for this URL.
        register_rest_route('jetpack/v4', '/identity-crisis/start-fresh', array('methods' => WP_REST_Server::EDITABLE, 'callback' => __CLASS__ . '::start_fresh_connection', 'permission_callback' => __CLASS__ . '::identity_crisis_mitigation_permission_check'));
        // Handles the request to migrate stats and subscribers during an identity crisis.
        register_rest_route('jetpack/v4', 'identity-crisis/migrate', array('methods' => WP_REST_Server::EDITABLE, 'callback' => __CLASS__ . '::migrate_stats_and_subscribers', 'permissison_callback' => __CLASS__ . '::identity_crisis_mitigation_permission_check'));
        // Return all modules
        self::route('module/all', 'Jetpack_Core_API_Module_List_Endpoint', WP_REST_Server::READABLE);
        // Activate many modules
        self::route('/module/all/active', 'Jetpack_Core_API_Module_List_Endpoint', WP_REST_Server::EDITABLE, NULL, array('modules' => array('default' => '', 'type' => 'array', 'required' => true, 'validate_callback' => __CLASS__ . '::validate_module_list'), 'active' => array('default' => true, 'type' => 'boolean', 'required' => false, 'validate_callback' => __CLASS__ . '::validate_boolean')));
        Jetpack::load_xml_rpc_client();
        // Return a single module and update it when needed
        self::route('/module/(?P<slug>[a-z\\-]+)', 'Jetpack_Core_API_Data', WP_REST_Server::READABLE, new Jetpack_IXR_Client(array('user_id' => get_current_user_id())));
        // Activate and deactivate a module
        self::route('/module/(?P<slug>[a-z\\-]+)/active', 'Jetpack_Core_API_Module_Toggle_Endpoint', WP_REST_Server::EDITABLE, new Jetpack_IXR_Client(), array('active' => array('default' => true, 'type' => 'boolean', 'required' => true, 'validate_callback' => __CLASS__ . '::validate_boolean')));
        // Update a module
        self::route('/module/(?P<slug>[a-z\\-]+)', 'Jetpack_Core_API_Data', WP_REST_Server::EDITABLE, new Jetpack_IXR_Client(array('user_id' => get_current_user_id())), self::get_updateable_parameters());
        // Get data for a specific module, i.e. Protect block count, WPCOM stats,
        // Akismet spam count, etc.
        self::route('/module/(?P<slug>[a-z\\-]+)/data', 'Jetpack_Core_API_Module_Data_Endpoint', WP_REST_Server::READABLE, NULL, array('range' => array('default' => 'day', 'type' => 'string', 'required' => false, 'validate_callback' => __CLASS__ . '::validate_string')));
        // Update any Jetpack module option or setting
        self::route('/settings', 'Jetpack_Core_API_Data', WP_REST_Server::EDITABLE, new Jetpack_IXR_Client(array('user_id' => get_current_user_id())), self::get_updateable_parameters('any'));
        // Update a module
        self::route('/settings/(?P<slug>[a-z\\-]+)', 'Jetpack_Core_API_Data', WP_REST_Server::EDITABLE, new Jetpack_IXR_Client(array('user_id' => get_current_user_id())), self::get_updateable_parameters());
        // Return miscellaneous settings
        register_rest_route('jetpack/v4', '/settings', array('methods' => WP_REST_Server::READABLE, 'callback' => __CLASS__ . '::get_settings', 'permission_callback' => __CLASS__ . '::view_admin_page_permission_check'));
        // Reset all Jetpack options
        register_rest_route('jetpack/v4', '/options/(?P<options>[a-z\\-]+)', array('methods' => WP_REST_Server::EDITABLE, 'callback' => __CLASS__ . '::reset_jetpack_options', 'permission_callback' => __CLASS__ . '::manage_modules_permission_check'));
        // Jumpstart
        register_rest_route('jetpack/v4', '/jumpstart', array('methods' => WP_REST_Server::EDITABLE, 'callback' => __CLASS__ . '::jumpstart_toggle', 'permission_callback' => __CLASS__ . '::manage_modules_permission_check', 'args' => array('active' => array('required' => true, 'validate_callback' => __CLASS__ . '::validate_boolean'))));
        // Updates: get number of plugin updates available
        register_rest_route('jetpack/v4', '/updates/plugins', array('methods' => WP_REST_Server::READABLE, 'callback' => __CLASS__ . '::get_plugin_update_count', 'permission_callback' => __CLASS__ . '::view_admin_page_permission_check'));
        // Dismiss Jetpack Notices
        register_rest_route('jetpack/v4', '/notice/(?P<notice>[a-z\\-_]+)', array('methods' => WP_REST_Server::EDITABLE, 'callback' => __CLASS__ . '::dismiss_notice', 'permission_callback' => __CLASS__ . '::view_admin_page_permission_check'));
        // Plugins: get list of all plugins.
        register_rest_route('jetpack/v4', '/plugins', array('methods' => WP_REST_Server::READABLE, 'callback' => __CLASS__ . '::get_plugins', 'permission_callback' => __CLASS__ . '::activate_plugins_permission_check'));
        // Plugins: check if the plugin is active.
        register_rest_route('jetpack/v4', '/plugin/(?P<plugin>[a-z\\/\\.\\-_]+)', array('methods' => WP_REST_Server::READABLE, 'callback' => __CLASS__ . '::get_plugin', 'permission_callback' => __CLASS__ . '::activate_plugins_permission_check'));
    }
 function wpcom_switch_blog_owner($new_master)
 {
     $request = array('new_blog_owner' => $new_master);
     // Tell wpcom about the change
     Jetpack::load_xml_rpc_client();
     $xml = new Jetpack_IXR_Client(array('user_id' => get_current_user_id()));
     $xml->query('jetpack.switchBlogOwner', $request);
 }
 static function send_data($data)
 {
     Jetpack::load_xml_rpc_client();
     // add an extra parameter to the URL so we can tell it's a sync action
     $url = add_query_arg('sync', '1', Jetpack::xmlrpc_api_url());
     $rpc = new Jetpack_IXR_Client(array('url' => $url, 'user_id' => get_current_user_id(), 'timeout' => 30));
     $result = $rpc->query('jetpack.syncActions', $data);
     if (!$result) {
         return $rpc->get_jetpack_error();
     }
     return $rpc->getResponse();
 }
 /**
  * @author zinigor
  * @covers Jetpack_Core_XMLRPC_Consumer_Endpoint
  * @requires PHP 5.2
  * @dataProvider true_false_provider
  */
 public function test_Jetpack_Core_API_XMLRPC_Consumer_Endpoint_privacy_check($query_success, $result)
 {
     Jetpack::load_xml_rpc_client();
     $xmlrpc_mock = $this->getMockBuilder('Jetpack_IXR_Client')->setMethods(array('query', 'getResponse'))->getMock();
     $endpoint = new WP_Test_Dummy_Xmlrpc_Consumer_Endpoint($xmlrpc_mock);
     $xmlrpc_mock->expects($this->once())->method('query')->with('jetpack.isSitePubliclyAccessible', home_url())->willReturn($query_success);
     if ($query_success) {
         $xmlrpc_mock->expects($this->once())->method('getResponse')->willReturn($result);
     } else {
         $xmlrpc_mock->expects($this->never())->method('getResponse');
     }
     $this->assertEquals($result, $endpoint->process(null));
 }
 /**
  * Verify that frame nonce exists, and if so, validate the nonce by calling WP.com.
  *
  * @since 4.4.0
  *
  * @return bool
  */
 public function is_frame_nonce_valid()
 {
     if (empty($_GET['frame-nonce'])) {
         return false;
     }
     Jetpack::load_xml_rpc_client();
     $xml = new Jetpack_IXR_Client();
     $xml->query('jetpack.verifyFrameNonce', sanitize_key($_GET['frame-nonce']));
     if ($xml->isError()) {
         return false;
     }
     return (bool) $xml->getResponse();
 }
 static function send_data($data, $codec_name, $sent_timestamp, $queue_id)
 {
     Jetpack::load_xml_rpc_client();
     $query_args = array('sync' => '1', 'codec' => $codec_name, 'timestamp' => $sent_timestamp, 'queue' => $queue_id);
     if (Jetpack::sync_idc_optin()) {
         $query_args['home'] = get_home_url();
         // Send home url option to check for Identity Crisis server-side
         $query_args['siteurl'] = get_site_url();
         // Send home url option to check for Identity Crisis server-side
     }
     $url = add_query_arg($query_args, Jetpack::xmlrpc_api_url());
     $rpc = new Jetpack_IXR_Client(array('url' => $url, 'user_id' => JETPACK_MASTER_USER, 'timeout' => 30));
     $result = $rpc->query('jetpack.syncActions', $data);
     if (!$result) {
         return $rpc->get_jetpack_error();
     }
     return $rpc->getResponse();
 }
 public function reindex_status()
 {
     $response = array('status' => 'ERROR');
     // Assume reindexing is done if it was not triggered in the first place
     if (false === Jetpack_Options::get_option('sync_bulk_reindexing')) {
         return array('status' => 'DONE');
     }
     Jetpack::load_xml_rpc_client();
     $client = new Jetpack_IXR_Client(array('user_id' => JETPACK_MASTER_USER));
     $client->query('jetpack.reindexStatus');
     if (!$client->isError()) {
         $response = $client->getResponse();
         if ('DONE' == $response['status']) {
             Jetpack_Options::delete_option('sync_bulk_reindexing');
         }
     }
     return $response;
 }
 /**
  * Iterates through expected items ( plugins or themes ) and compares them to actual results.
  *
  * @param $items 'plugin' or 'theme'
  */
 function log_items($items)
 {
     $num_items_updated = 0;
     $num_items_failed = 0;
     $item_results = $this->get_successful_updates($items);
     $items_failed = array();
     foreach ($this->autoupdate_expected[$items] as $item) {
         if (in_array($item, $item_results)) {
             $num_items_updated++;
             $this->log[$items][$item] = true;
         } else {
             $num_items_failed++;
             $this->log[$items][$item] = new WP_Error("{$items}-fail", $this->get_error_message($item, $type = $items));
             $items_failed[] = $item;
         }
     }
     if ($num_items_updated) {
         $this->jetpack->stat("autoupdates/{$items}-success", $num_items_updated);
     }
     if ($num_items_failed) {
         // bump stats
         $this->jetpack->stat("autoupdates/{$items}-fail", $num_items_failed);
         Jetpack::load_xml_rpc_client();
         $xml = new Jetpack_IXR_Client(array('user_id' => get_current_user_id()));
         $request = array('plugins' => $items_failed, 'blog_id' => Jetpack_Options::get_option('id'));
         $xml->query('jetpack.debug_autoupdate', $request);
     }
 }
 function options_save_tumblr()
 {
     // Nonce check
     check_admin_referer('save_tumblr_blog_' . $_REQUEST['connection']);
     $id = $_POST['connection'];
     $options = array('tumblr_base_hostname' => $_POST['selected_id']);
     Jetpack::load_xml_rpc_client();
     $xml = new Jetpack_IXR_Client();
     $xml->query('jetpack.setPublicizeOptions', $id, $options);
     if (!$xml->isError()) {
         $response = $xml->getResponse();
         Jetpack::update_option('publicize_connections', $response);
     }
     $this->globalization();
 }
 static function send_data($data, $codec_name, $sent_timestamp, $queue_id)
 {
     Jetpack::load_xml_rpc_client();
     $url = add_query_arg(array('sync' => '1', 'codec' => $codec_name, 'timestamp' => $sent_timestamp, 'queue' => $queue_id), Jetpack::xmlrpc_api_url());
     $rpc = new Jetpack_IXR_Client(array('url' => $url, 'user_id' => JETPACK_MASTER_USER, 'timeout' => 30));
     $result = $rpc->query('jetpack.syncActions', $data);
     if (!$result) {
         return $rpc->get_jetpack_error();
     }
     return $rpc->getResponse();
 }
Esempio n. 11
0
 public function monitor_get_last_downtime()
 {
     //		if ( $last_down = get_transient( 'monitor_last_downtime' ) ) {
     //			return $last_down;
     //		}
     Jetpack::load_xml_rpc_client();
     $xml = new Jetpack_IXR_Client(array('user_id' => get_current_user_id()));
     $xml->query('jetpack.monitor.getLastDowntime');
     if ($xml->isError()) {
         return new WP_Error('monitor-downtime', $xml->getErrorMessage());
     }
     set_transient('monitor_last_downtime', $xml->getResponse(), 10 * MINUTE_IN_SECONDS);
     return $xml->getResponse();
 }
Esempio n. 12
0
 public function monitor_get_last_downtime()
 {
     Jetpack::load_xml_rpc_client();
     $xml = new Jetpack_IXR_Client(array('user_id' => get_current_user_id()));
     $xml->query('jetpack.monitor.getLastDowntime');
     if ($xml->isError()) {
         return new WP_Error('monitor-downtime', $xml->getErrorMessage());
     }
     return $xml->getResponse();
 }
Esempio n. 13
0
 /**
  * The function that actually handles the login!
  */
 function handle_login()
 {
     $wpcom_nonce = sanitize_key($_GET['sso_nonce']);
     $wpcom_user_id = (int) $_GET['user_id'];
     $result = sanitize_key($_GET['result']);
     Jetpack::load_xml_rpc_client();
     $xml = new Jetpack_IXR_Client(array('user_id' => get_current_user_id()));
     $xml->query('jetpack.sso.validateResult', $wpcom_nonce, $wpcom_user_id);
     if ($xml->isError()) {
         wp_die(sprintf('%s: %s', $xml->getErrorCode(), $xml->getErrorMessage()));
     }
     $user_data = $xml->getResponse();
     if (empty($user_data)) {
         wp_die(__('Error, invalid response data.', 'jetpack'));
     }
     $user_data = (object) $user_data;
     $user = null;
     /**
      * Fires before Jetpack's SSO modifies the log in form.
      *
      * @module sso
      *
      * @since 2.6.0
      *
      * @param object $user_data User login information.
      */
     do_action('jetpack_sso_pre_handle_login', $user_data);
     /**
      * Is it required to have 2-step authentication enabled on WordPress.com to use SSO?
      *
      * @module sso
      *
      * @since 2.8.0
      *
      * @param bool get_option( 'jetpack_sso_require_two_step' ) Does SSO require 2-step authentication?
      */
     $require_two_step = apply_filters('jetpack_sso_require_two_step', get_option('jetpack_sso_require_two_step'));
     if ($require_two_step && 0 == (int) $user_data->two_step_enabled) {
         $this->user_data = $user_data;
         /** This filter is documented in core/src/wp-includes/pluggable.php */
         do_action('wp_login_failed', $user_data->login);
         add_action('login_message', array($this, 'error_msg_enable_two_step'));
         return;
     }
     if (isset($_GET['state']) && 0 < strpos($_GET['state'], '|')) {
         list($state, $nonce) = explode('|', $_GET['state']);
         if (wp_verify_nonce($nonce, $state)) {
             if ('sso-link-user' == $state) {
                 $user = wp_get_current_user();
                 update_user_meta($user->ID, 'wpcom_user_id', $user_data->ID);
                 add_filter('login_redirect', array(__CLASS__, 'profile_page_url'));
             }
         } else {
             wp_nonce_ays();
         }
     }
     if (empty($user)) {
         $user = $this->get_user_by_wpcom_id($user_data->ID);
     }
     // If we don't have one by wpcom_user_id, try by the email?
     if (empty($user) && self::match_by_email()) {
         $user = get_user_by('email', $user_data->email);
         if ($user) {
             update_user_meta($user->ID, 'wpcom_user_id', $user_data->ID);
         }
     }
     // If we've still got nothing, create the user.
     if (empty($user) && (get_option('users_can_register') || self::new_user_override())) {
         // If not matching by email we still need to verify the email does not exist
         // or this blows up
         /**
          * If match_by_email is true, we know the email doesn't exist, as it would have
          * been found in the first pass.  If get_user_by( 'email' ) doesn't find the
          * user, then we know that email is unused, so it's safe to add.
          */
         if (self::match_by_email() || !get_user_by('email', $user_data->email)) {
             $username = $user_data->login;
             if (username_exists($username)) {
                 $username = $user_data->login . '_' . $user_data->ID;
             }
             $tries = 0;
             while (username_exists($username)) {
                 $username = $user_data->login . '_' . $user_data->ID . '_' . mt_rand();
                 if ($tries++ >= 5) {
                     wp_die(__("Error: Couldn't create suitable username.", 'jetpack'));
                 }
             }
             $password = wp_generate_password(20);
             $user_id = wp_create_user($username, $password, $user_data->email);
             $user = get_userdata($user_id);
             $user->display_name = $user_data->display_name;
             $user->first_name = $user_data->first_name;
             $user->last_name = $user_data->last_name;
             $user->url = $user_data->url;
             $user->description = $user_data->description;
             wp_update_user($user);
             update_user_meta($user->ID, 'wpcom_user_id', $user_data->ID);
         } else {
             $this->user_data = $user_data;
             // do_action( 'wp_login_failed', $user_data->login );
             add_action('login_message', array($this, 'error_msg_email_already_exists'));
             return;
         }
     }
     /**
      * Fires after we got login information from WordPress.com.
      *
      * @module sso
      *
      * @since 2.6.0
      *
      * @param array $user WordPress.com User information.
      * @param object $user_data User Login information.
      */
     do_action('jetpack_sso_handle_login', $user, $user_data);
     if ($user) {
         // Cache the user's details, so we can present it back to them on their user screen.
         update_user_meta($user->ID, 'wpcom_user_data', $user_data);
         $remember = false;
         if (!empty($_COOKIE['jetpack_sso_remember_me'])) {
             $remember = true;
             // And then purge it
             setcookie('jetpack_sso_remember_me', ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN);
         }
         /**
          * Filter the remember me value.
          *
          * @module sso
          *
          * @since 2.8.0
          *
          * @param bool $remember Is the remember me option checked?
          */
         $remember = apply_filters('jetpack_remember_login', $remember);
         wp_set_auth_cookie($user->ID, $remember);
         /** This filter is documented in core/src/wp-includes/user.php */
         do_action('wp_login', $user->user_login, $user);
         $_request_redirect_to = isset($_REQUEST['redirect_to']) ? $_REQUEST['redirect_to'] : '';
         $redirect_to = user_can($user, 'edit_posts') ? admin_url() : self::profile_page_url();
         // If we have a saved redirect to request in a cookie
         if (!empty($_COOKIE['jetpack_sso_redirect_to'])) {
             // Set that as the requested redirect to
             $redirect_to = $_request_redirect_to = esc_url_raw($_COOKIE['jetpack_sso_redirect_to']);
             // And then purge it
             setcookie('jetpack_sso_redirect_to', ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN);
         }
         wp_safe_redirect(apply_filters('login_redirect', $redirect_to, $_request_redirect_to, $user));
         exit;
     }
     $this->user_data = $user_data;
     /** This filter is documented in core/src/wp-includes/pluggable.php */
     do_action('wp_login_failed', $user_data->login);
     add_action('login_message', array($this, 'cant_find_user'));
 }
 private static function get_jetpack_user()
 {
     if (!class_exists('Jetpack')) {
         return false;
     }
     Jetpack::load_xml_rpc_client();
     $xml = new Jetpack_IXR_ClientMulticall(array('user_id' => get_current_user_id()));
     $xml->addCall('wpcom.getUserID');
     $xml->addCall('akismet.getAPIKey');
     $xml->query();
     Akismet::log(compact('xml'));
     if (!$xml->isError()) {
         $responses = $xml->getResponse();
         if (count($responses) > 1) {
             $api_key = array_shift($responses[0]);
             $user_id = (int) array_shift($responses[1]);
             return compact('api_key', 'user_id');
         }
     }
     return false;
 }
 public function bump_stats()
 {
     $instance = Jetpack::init();
     $log = array();
     // Bump numbers
     if (!empty($this->success['plugin'])) {
         $instance->stat('autoupdates/plugin-success', count($this->success['plugin']));
         $log['plugins_success'] = $this->success['plugin'];
     }
     if (!empty($this->failed['plugin'])) {
         $instance->stat('autoupdates/plugin-fail', count($this->failed['plugin']));
         $log['plugins_failed'] = $this->failed['plugin'];
     }
     if (!empty($this->success['theme'])) {
         $instance->stat('autoupdates/theme-success', count($this->success['theme']));
         $log['themes_success'] = $this->success['theme'];
     }
     if (!empty($this->failed['theme'])) {
         $instance->stat('autoupdates/theme-fail', count($this->failed['theme']));
         $log['themes_failed'] = $this->failed['theme'];
     }
     $instance->do_stats('server_side');
     // Send a more detailed log to logstash
     if (!empty($log)) {
         Jetpack::load_xml_rpc_client();
         $xml = new Jetpack_IXR_Client(array('user_id' => get_current_user_id()));
         $log['blog_id'] = Jetpack_Options::get_option('id');
         $xml->query('jetpack.debug_autoupdate', $log);
     }
 }
Esempio n. 16
0
 /**
  * Helper method for multicall XMLRPC.
  */
 function xmlrpc_async_call()
 {
     static $client = array();
     if (!$client) {
         Jetpack::load_xml_rpc_client();
         $client[0] =& new Jetpack_IXR_ClientMulticall(array('user_id' => get_current_user_id()));
         ignore_user_abort(true);
         add_action('shutdown', array('Jetpack', 'xmlrpc_async_call'));
     }
     $args = func_get_args();
     if (!empty($args[0])) {
         call_user_func_array(array(&$client[0], 'addCall'), $args);
     } elseif (!empty($client[0]->calls)) {
         flush();
         $client[0]->query();
     }
 }
Esempio n. 17
0
 function fetch_subscriber_count()
 {
     $subs_count = get_transient('wpcom_subscribers_total');
     if (FALSE === $subs_count || 'failed' == $subs_count['status']) {
         Jetpack::load_xml_rpc_client();
         $xml = new Jetpack_IXR_Client(array('user_id' => JETPACK_MASTER_USER));
         $xml->query('jetpack.fetchSubscriberCount');
         if ($xml->isError()) {
             // if we get an error from .com, set the status to failed so that we will try again next time the data is requested
             $subs_count = array('status' => 'failed', 'code' => $xml->getErrorCode(), 'message' => $xml->getErrorMessage(), 'value' => isset($subs_count['value']) ? $subs_count['value'] : 0);
         } else {
             $subs_count = array('status' => 'success', 'value' => $xml->getResponse());
         }
         set_transient('wpcom_subscribers_total', $subs_count, 3600);
         // try to cache the result for at least 1 hour
     }
     return $subs_count;
 }
Esempio n. 18
0
 function handle_login()
 {
     $wpcom_nonce = sanitize_key($_GET['sso_nonce']);
     $wpcom_user_id = (int) $_GET['user_id'];
     $result = sanitize_key($_GET['result']);
     Jetpack::load_xml_rpc_client();
     $xml = new Jetpack_IXR_Client(array('user_id' => get_current_user_id()));
     $xml->query('jetpack.sso.validateResult', $wpcom_nonce, $wpcom_user_id);
     if ($xml->isError()) {
         wp_die(sprintf('%s: %s', $xml->getErrorCode(), $xml->getErrorMessage()));
     }
     $user_data = $xml->getResponse();
     if (empty($user_data)) {
         wp_die(__('Error, invalid response data.', 'jetpack'));
     }
     $user_data = (object) $user_data;
     $user = null;
     do_action('jetpack_sso_pre_handle_login', $user_data);
     // Check to see if having two step enable on wpcom is a requirement to login here
     $require_two_step = apply_filters('jetpack_sso_require_two_step', get_option('jetpack_sso_require_two_step'));
     if ($require_two_step && 0 == (int) $user_data->two_step_enabled) {
         $this->user_data = $user_data;
         do_action('wp_login_failed', $user_data->login);
         add_action('login_message', array($this, 'error_msg_enable_two_step'));
         return;
     }
     if (isset($_GET['state']) && 0 < strpos($_GET['state'], '|')) {
         list($state, $nonce) = explode('|', $_GET['state']);
         if (wp_verify_nonce($nonce, $state)) {
             if ('sso-link-user' == $state) {
                 $user = wp_get_current_user();
                 update_user_meta($user->ID, 'wpcom_user_id', $user_data->ID);
                 add_filter('login_redirect', array(__CLASS__, 'profile_page_url'));
             }
         } else {
             wp_nonce_ays();
         }
     }
     if (empty($user)) {
         $user = $this->get_user_by_wpcom_id($user_data->ID);
     }
     // If we don't have one by wpcom_user_id, try by the email?
     if (empty($user) && self::match_by_email()) {
         $user = get_user_by('email', $user_data->email);
         if ($user) {
             update_user_meta($user->ID, 'wpcom_user_id', $user_data->ID);
         }
     }
     // If we've still got nothing, create the user.
     if (empty($user) && (get_option('users_can_register') || self::new_user_override())) {
         // If not matching by email we still need to verify the email does not exist
         // or this blows up
         if (!self::match_by_email() && !get_user_by('email', $user_data->email)) {
             $username = $user_data->login;
             if (username_exists($username)) {
                 $username = $user_data->login . '_' . $user_data->ID;
             }
             $tries = 0;
             while (username_exists($username)) {
                 $username = $user_data->login . '_' . $user_data->ID . '_' . mt_rand();
                 if ($tries++ >= 5) {
                     wp_die(__("Error: Couldn't create suitable username.", 'jetpack'));
                 }
             }
             $password = wp_generate_password(20);
             $user_id = wp_create_user($username, $password, $user_data->email);
             $user = get_userdata($user_id);
             $user->display_name = $user_data->display_name;
             $user->first_name = $user_data->first_name;
             $user->last_name = $user_data->last_name;
             $user->url = $user_data->url;
             $user->description = $user_data->description;
             wp_update_user($user);
             update_user_meta($user->ID, 'wpcom_user_id', $user_data->ID);
         }
     }
     do_action('jetpack_sso_handle_login', $user, $user_data);
     if ($user) {
         // Cache the user's details, so we can present it back to them on their user screen.
         update_user_meta($user->ID, 'wpcom_user_data', $user_data);
         // Set remember me value
         $remember = apply_filters('jetpack_remember_login', false);
         wp_set_auth_cookie($user->ID, $remember);
         // Run the WP core login action
         do_action('wp_login', $user->user_login, $user);
         $_request_redirect_to = isset($_REQUEST['redirect_to']) ? $_REQUEST['redirect_to'] : '';
         $redirect_to = user_can($user, 'edit_posts') ? admin_url() : self::profile_page_url();
         // If we have a saved redirect to request in a cookie
         if (!empty($_COOKIE['jetpack_sso_redirect_to'])) {
             // Set that as the requested redirect to
             $redirect_to = $_request_redirect_to = esc_url_raw($_COOKIE['jetpack_sso_redirect_to']);
             // And then purge it
             setcookie('jetpack_sso_redirect_to', ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN);
         }
         wp_safe_redirect(apply_filters('login_redirect', $redirect_to, $_request_redirect_to, $user));
         exit;
     }
     $this->user_data = $user_data;
     do_action('wp_login_failed', $user_data->login);
     add_action('login_message', array($this, 'cant_find_user'));
 }
 /**
  * Calls WPCOM through authenticated request to create, regenerate or delete the Post by Email address.
  * @todo: When all settings are updated to use endpoints, move this to the Post by Email module and replace __process_ajax_proxy_request.
  *
  * @since 4.1.0
  *
  * @param string $endpoint Process to call on WPCOM to create, regenerate or delete the Post by Email address.
  * @param string $error	   Error message to return.
  *
  * @return array
  */
 private static function _process_post_by_email($endpoint, $error)
 {
     if (!current_user_can('edit_posts')) {
         return array('message' => $error);
     }
     Jetpack::load_xml_rpc_client();
     $xml = new Jetpack_IXR_Client(array('user_id' => get_current_user_id()));
     $xml->query($endpoint);
     if ($xml->isError()) {
         return array('message' => $error);
     }
     $response = $xml->getResponse();
     if (empty($response)) {
         return array('message' => $error);
     }
     // Used only in Jetpack_Core_Json_Api_Endpoints::get_remote_value.
     update_option('post_by_email_address', $response);
     return $response;
 }
Esempio n. 20
0
 function handle_login()
 {
     $wpcom_nonce = sanitize_key($_GET['sso_nonce']);
     $wpcom_user_id = (int) $_GET['user_id'];
     $result = sanitize_key($_GET['result']);
     Jetpack::load_xml_rpc_client();
     $xml = new Jetpack_IXR_Client(array('user_id' => get_current_user_id()));
     $xml->query('jetpack.sso.validateResult', $wpcom_nonce, $wpcom_user_id);
     if ($xml->isError()) {
         wp_die(sprintf('%s: %s', $xml->getErrorCode(), $xml->getErrorMessage()));
     }
     $user_data = $xml->getResponse();
     if (empty($user_data)) {
         wp_die(__('Error, invalid response data.', 'jetpack'));
     }
     $user_data = (object) $user_data;
     $user = null;
     do_action('jetpack_sso_pre_handle_login', $user_data);
     if (isset($_GET['state']) && 0 < strpos($_GET['state'], '|')) {
         list($state, $nonce) = explode('|', $_GET['state']);
         if (wp_verify_nonce($nonce, $state)) {
             if ('sso-link-user' == $state) {
                 $user = wp_get_current_user();
                 update_user_meta($user->ID, 'wpcom_user_id', $user_data->ID);
                 add_filter('login_redirect', array(__CLASS__, 'profile_page_url'));
             }
         } else {
             wp_nonce_ays();
         }
     }
     if (empty($user)) {
         $user = $this->get_user_by_wpcom_id($user_data->ID);
     }
     // If we don't have one by wpcom_user_id, try by the email?
     if (empty($user) && self::match_by_email()) {
         $user = get_user_by('email', $user_data->email);
         if ($user) {
             update_user_meta($user->ID, 'wpcom_user_id', $user_data->ID);
         }
     }
     // If we've still got nothing, create the user.
     if (empty($user) && (get_option('users_can_register') || self::new_user_override())) {
         $username = $user_data->login;
         if (username_exists($username)) {
             $username = $user_data->login . '_' . $user_data->ID;
         }
         $tries = 0;
         while (username_exists($username)) {
             $username = $user_data->login . '_' . $user_data->ID . '_' . mt_rand();
             if ($tries++ >= 5) {
                 wp_die(__("Error: Couldn't create suitable username.", 'jetpack'));
             }
         }
         $password = wp_generate_password(20);
         $user_id = wp_create_user($username, $password, $user_data->email);
         $user = get_userdata($user_id);
         $user->display_name = $user_data->display_name;
         $user->first_name = $user_data->first_name;
         $user->last_name = $user_data->last_name;
         $user->url = $user_data->url;
         $user->description = $user_data->description;
         wp_update_user($user);
         update_user_meta($user->ID, 'wpcom_user_id', $user_data->ID);
     }
     do_action('jetpack_sso_handle_login', $user, $user_data);
     if ($user) {
         // Cache the user's details, so we can present it back to them on their user screen.
         update_user_meta($user->ID, 'wpcom_user_data', $user_data);
         wp_set_auth_cookie($user->ID);
         $_request_redirect_to = isset($_REQUEST['redirect_to']) ? $_REQUEST['redirect_to'] : '';
         $redirect_to = user_can($user, 'edit_posts') ? admin_url() : self::profile_page_url();
         wp_safe_redirect(apply_filters('login_redirect', $redirect_to, $_request_redirect_to, $user));
         exit;
     }
     $this->user_data = $user_data;
     add_action('login_message', array($this, 'cant_find_user'));
 }
Esempio n. 21
0
 /**
  * Remote Query
  *
  * Performs a remote XML-RPC query using Jetpack's IXR Client. And also
  * appends some useful stuff about this setup to the query.
  *
  * @return the Jetpack_IXR_Client object after querying.
  */
 function query($method, $args = null)
 {
     $options = $this->get_options();
     Jetpack::load_xml_rpc_client();
     $xml = new Jetpack_IXR_Client(array('user_id' => JETPACK_MASTER_USER));
     $params = array('args' => $args, 'video_blog_id' => $options['blog_id'], 'caps' => array());
     // Let Jetpack know about our local caps.
     foreach (array('read_videos', 'edit_videos', 'delete_videos', 'upload_videos') as $cap) {
         if ($this->can($cap)) {
             $params['caps'][] = $cap;
         }
     }
     $xml->query($method, $params);
     if ($xml->isError()) {
         return new WP_Error('xml_rpc_error', 'An XML-RPC error has occurred.');
     }
     $response = $xml->getResponse();
     // If there's any metadata with the response, save it for future use.
     if (is_array($response) && isset($response['meta'])) {
         $options = $this->get_options();
         if ($response['meta'] !== $options['meta']) {
             $options['meta'] = array_merge($options['meta'], $response['meta']);
             $this->update_options($options);
         }
     }
     if (is_array($response) && isset($response['result'])) {
         return $response['result'];
     }
     return $response;
 }
Esempio n. 22
0
 public function deactivate_monitor()
 {
     Jetpack::load_xml_rpc_client();
     $xml = new Jetpack_IXR_Client(array('user_id' => get_current_user_id()));
     $xml->query('jetpack.monitor.deactivate');
     if ($xml->isError()) {
         wp_die(sprintf('%s: %s', $xml->getErrorCode(), $xml->getErrorMessage()));
     }
     return true;
 }
Esempio n. 23
0
 function delete_post_by_email_address()
 {
     Jetpack::load_xml_rpc_client();
     $xml = new Jetpack_IXR_Client(array('user_id' => get_current_user_id()));
     $xml->query('jetpack.deletePostByEmailAddress');
     if ($xml->isError()) {
         echo json_encode(array('response' => 'error', 'message' => __('Unable to disable your Post By Email address. Please try again later.', 'jetpack')));
         die;
     }
     $response = $xml->getResponse();
     if (empty($response)) {
         echo json_encode(array('response' => 'error', 'message' => __('Unable to disable your Post By Email address. Please try again later.', 'jetpack')));
         die;
     }
     echo $response;
     die;
 }
 public function setUp()
 {
     parent::setUp();
     Jetpack::load_xml_rpc_client();
 }
Esempio n. 25
0
 /**
  * Request an api key from wordpress.com
  *
  * @return bool | string
  */
 public function get_protect_key()
 {
     $protect_blog_id = Jetpack_Protect_Module::get_main_blog_jetpack_id();
     // If we can't find the the blog id, that means we are on multisite, and the main site never connected
     // the protect api key is linked to the main blog id - instruct the user to connect their main blog
     if (!$protect_blog_id) {
         $this->api_key_error = __('Your main blog is not connected to WordPress.com. Please connect to get an API key.', 'jetpack');
         return false;
     }
     $request = array('jetpack_blog_id' => $protect_blog_id, 'bruteprotect_api_key' => get_site_option('bruteprotect_api_key'), 'multisite' => '0');
     // Send the number of blogs on the network if we are on multisite
     if (is_multisite()) {
         $request['multisite'] = get_blog_count();
         if (!$request['multisite']) {
             global $wpdb;
             $request['multisite'] = $wpdb->get_var("SELECT COUNT(blog_id) as c FROM {$wpdb->blogs} WHERE spam = '0' AND deleted = '0' and archived = '0'");
         }
     }
     // Request the key
     Jetpack::load_xml_rpc_client();
     $xml = new Jetpack_IXR_Client(array('user_id' => get_current_user_id()));
     $xml->query('jetpack.protect.requestKey', $request);
     // Hmm, can't talk to wordpress.com
     if ($xml->isError()) {
         $code = $xml->getErrorCode();
         $message = $xml->getErrorMessage();
         $this->api_key_error = sprintf(__('Error connecting to WordPress.com. Code: %1$s, %2$s', 'jetpack'), $code, $message);
         return false;
     }
     $response = $xml->getResponse();
     // Hmm. Can't talk to the protect servers ( api.bruteprotect.com )
     if (!isset($response['data'])) {
         $this->api_key_error = __('No reply from Jetpack servers', 'jetpack');
         return false;
     }
     // There was an issue generating the key
     if (empty($response['success'])) {
         $this->api_key_error = $response['data'];
         return false;
     }
     // Key generation successful!
     $active_plugins = Jetpack::get_active_plugins();
     // We only want to deactivate BruteProtect if we successfully get a key
     if (in_array('bruteprotect/bruteprotect.php', $active_plugins)) {
         Jetpack_Client_Server::deactivate_plugin('bruteprotect/bruteprotect.php', 'BruteProtect');
     }
     $key = $response['data'];
     update_site_option('jetpack_protect_key', $key);
     return $key;
 }
Esempio n. 26
0
 /**
  * The function that actually handles the login!
  */
 function handle_login()
 {
     $wpcom_nonce = sanitize_key($_GET['sso_nonce']);
     $wpcom_user_id = (int) $_GET['user_id'];
     Jetpack::load_xml_rpc_client();
     $xml = new Jetpack_IXR_Client(array('user_id' => get_current_user_id()));
     $xml->query('jetpack.sso.validateResult', $wpcom_nonce, $wpcom_user_id);
     if ($xml->isError()) {
         $error_message = sanitize_text_field(sprintf('%s: %s', $xml->getErrorCode(), $xml->getErrorMessage()));
         JetpackTracking::record_user_event('sso_login_failed', array('error_message' => $error_message));
         wp_die($error_message);
     }
     $user_data = $xml->getResponse();
     if (empty($user_data)) {
         JetpackTracking::record_user_event('sso_login_failed', array('error_message' => 'invalid_response_data'));
         wp_die(__('Error, invalid response data.', 'jetpack'));
     }
     $user_data = (object) $user_data;
     $user = null;
     /**
      * Fires before Jetpack's SSO modifies the log in form.
      *
      * @module sso
      *
      * @since 2.6.0
      *
      * @param object $user_data WordPress.com User information.
      */
     do_action('jetpack_sso_pre_handle_login', $user_data);
     if (Jetpack_SSO_Helpers::is_two_step_required() && 0 === (int) $user_data->two_step_enabled) {
         $this->user_data = $user_data;
         JetpackTracking::record_user_event('sso_login_failed', array('error_message' => 'error_msg_enable_two_step'));
         /** This filter is documented in core/src/wp-includes/pluggable.php */
         do_action('wp_login_failed', $user_data->login);
         add_filter('login_message', array($this, 'error_msg_enable_two_step'));
         return;
     }
     $user_found_with = '';
     if (empty($user) && isset($user_data->external_user_id)) {
         $user_found_with = 'external_user_id';
         $user = get_user_by('id', intval($user_data->external_user_id));
         if ($user) {
             update_user_meta($user->ID, 'wpcom_user_id', $user_data->ID);
         }
     }
     // If we don't have one by wpcom_user_id, try by the email?
     if (empty($user) && Jetpack_SSO_Helpers::match_by_email()) {
         $user_found_with = 'match_by_email';
         $user = get_user_by('email', $user_data->email);
         if ($user) {
             update_user_meta($user->ID, 'wpcom_user_id', $user_data->ID);
         }
     }
     // If we've still got nothing, create the user.
     if (empty($user) && (get_option('users_can_register') || Jetpack_SSO_Helpers::new_user_override())) {
         // If not matching by email we still need to verify the email does not exist
         // or this blows up
         /**
          * If match_by_email is true, we know the email doesn't exist, as it would have
          * been found in the first pass.  If get_user_by( 'email' ) doesn't find the
          * user, then we know that email is unused, so it's safe to add.
          */
         if (Jetpack_SSO_Helpers::match_by_email() || !get_user_by('email', $user_data->email)) {
             $username = $user_data->login;
             if (username_exists($username)) {
                 $username = $user_data->login . '_' . $user_data->ID;
             }
             $tries = 0;
             while (username_exists($username)) {
                 $username = $user_data->login . '_' . $user_data->ID . '_' . mt_rand();
                 if ($tries++ >= 5) {
                     JetpackTracking::record_user_event('sso_login_failed', array('error_message' => 'could_not_create_username'));
                     wp_die(__("Error: Couldn't create suitable username.", 'jetpack'));
                 }
             }
             $user_found_with = Jetpack_SSO_Helpers::new_user_override() ? 'user_created_new_user_override' : 'user_created_users_can_register';
             $password = wp_generate_password(20);
             $user_id = wp_create_user($username, $password, $user_data->email);
             $user = get_userdata($user_id);
             $user->display_name = $user_data->display_name;
             $user->first_name = $user_data->first_name;
             $user->last_name = $user_data->last_name;
             $user->url = $user_data->url;
             $user->description = $user_data->description;
             wp_update_user($user);
             update_user_meta($user->ID, 'wpcom_user_id', $user_data->ID);
         } else {
             JetpackTracking::record_user_event('sso_login_failed', array('error_message' => 'error_msg_email_already_exists'));
             $this->user_data = $user_data;
             add_action('login_message', array($this, 'error_msg_email_already_exists'));
             return;
         }
     }
     /**
      * Fires after we got login information from WordPress.com.
      *
      * @module sso
      *
      * @since 2.6.0
      *
      * @param array  $user      Local User information.
      * @param object $user_data WordPress.com User Login information.
      */
     do_action('jetpack_sso_handle_login', $user, $user_data);
     if ($user) {
         // Cache the user's details, so we can present it back to them on their user screen
         update_user_meta($user->ID, 'wpcom_user_data', $user_data);
         $remember = false;
         if (!empty($_COOKIE['jetpack_sso_remember_me'])) {
             $remember = true;
             // And then purge it
             setcookie('jetpack_sso_remember_me', ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN);
         }
         /**
          * Filter the remember me value.
          *
          * @module sso
          *
          * @since 2.8.0
          *
          * @param bool $remember Is the remember me option checked?
          */
         $remember = apply_filters('jetpack_remember_login', $remember);
         wp_set_auth_cookie($user->ID, $remember);
         /** This filter is documented in core/src/wp-includes/user.php */
         do_action('wp_login', $user->user_login, $user);
         wp_set_current_user($user->ID);
         $_request_redirect_to = isset($_REQUEST['redirect_to']) ? esc_url_raw($_REQUEST['redirect_to']) : '';
         $redirect_to = user_can($user, 'edit_posts') ? admin_url() : self::profile_page_url();
         // If we have a saved redirect to request in a cookie
         if (!empty($_COOKIE['jetpack_sso_redirect_to'])) {
             // Set that as the requested redirect to
             $redirect_to = $_request_redirect_to = esc_url_raw($_COOKIE['jetpack_sso_redirect_to']);
             // And then purge it
             setcookie('jetpack_sso_redirect_to', ' ', time() - YEAR_IN_SECONDS, COOKIEPATH, COOKIE_DOMAIN);
         }
         $is_user_connected = Jetpack::is_user_connected($user->ID);
         JetpackTracking::record_user_event('sso_user_logged_in', array('user_found_with' => $user_found_with, 'user_connected' => (bool) $is_user_connected, 'user_role' => Jetpack::translate_current_user_to_role()));
         if (!$is_user_connected) {
             $calypso_env = !empty($_GET['calypso_env']) ? sanitize_key($_GET['calypso_env']) : '';
             wp_safe_redirect(add_query_arg(array('redirect_to' => $redirect_to, 'request_redirect_to' => $_request_redirect_to, 'calypso_env' => $calypso_env, 'jetpack-sso-auth-redirect' => '1'), admin_url()));
             exit;
         }
         wp_safe_redirect(apply_filters('login_redirect', $redirect_to, $_request_redirect_to, $user));
         exit;
     }
     add_filter('jetpack_sso_default_to_sso_login', '__return_false');
     JetpackTracking::record_user_event('sso_login_failed', array('error_message' => 'cant_find_user'));
     $this->user_data = $user_data;
     /** This filter is documented in core/src/wp-includes/pluggable.php */
     do_action('wp_login_failed', $user_data->login);
     add_filter('login_message', array($this, 'cant_find_user'));
 }
Esempio n. 27
0
 /**
  * Pings the WordPress.com Mirror Site for the specified options.
  *
  * @param string|array $option_names The option names to request from the WordPress.com Mirror Site
  *
  * @return array An associative array of the option values as stored in the WordPress.com Mirror Site
  */
 public static function get_cloud_site_options($option_names)
 {
     $option_names = array_filter((array) $option_names, 'is_string');
     Jetpack::load_xml_rpc_client();
     $xml = new Jetpack_IXR_Client(array('user_id' => JETPACK_MASTER_USER));
     $xml->query('jetpack.fetchSiteOptions', $option_names);
     if ($xml->isError()) {
         return array_flip($option_names);
     }
     $cloud_site_options = $xml->getResponse();
     return $cloud_site_options;
 }
Esempio n. 28
0
 public static function get_cloud_site_options($option_names)
 {
     $option_names = array_filter((array) $option_names, 'is_string');
     Jetpack::load_xml_rpc_client();
     $xml = new Jetpack_IXR_Client(array('user_id' => get_current_user_id()));
     $xml->query('jetpack.fetchSiteOptions', $option_names);
     if ($xml->isError()) {
         return array_flip($option_names);
     }
     $cloud_site_options = $xml->getResponse();
     // If we want to intentionally jumble the results to test it ...
     if (isset($_GET['spoof_identity_crisis'])) {
         foreach ($cloud_site_options as $key => $value) {
             $cloud_site_options[$key] = wp_generate_password();
         }
     }
     return $cloud_site_options;
 }
Esempio n. 29
0
 public function jetpack_disconnect()
 {
     if (empty($_GET['disconnect']) || 'gplus' != $_GET['disconnect']) {
         return;
     }
     global $current_user;
     // security check - did we actually want to disconnect?
     $nonce = $_GET['_wpnonce'];
     if (!wp_verify_nonce($nonce, 'disconnect-gplus')) {
         return;
     }
     $connections = get_option('gplus_authors', array());
     Jetpack::load_xml_rpc_client();
     $xml = new Jetpack_IXR_Client();
     $xml->query('jetpack.disconnectGooglePlus', $connections[$current_user->ID]['id']);
     if (!$xml->isError()) {
         unset($connections[$current_user->ID]);
         update_option('gplus_authors', $connections);
     } else {
         // @todo error
     }
 }
Esempio n. 30
0
 /**
  * Helper method for multicall XMLRPC.
  */
 public static function xmlrpc_async_call()
 {
     global $blog_id;
     static $clients = array();
     $client_blog_id = is_multisite() ? $blog_id : 0;
     if (!isset($clients[$client_blog_id])) {
         Jetpack::load_xml_rpc_client();
         $clients[$client_blog_id] = new Jetpack_IXR_ClientMulticall(array('user_id' => JETPACK_MASTER_USER));
         ignore_user_abort(true);
         add_action('shutdown', array('Jetpack', 'xmlrpc_async_call'));
     }
     $args = func_get_args();
     if (!empty($args[0])) {
         call_user_func_array(array($clients[$client_blog_id], 'addCall'), $args);
     } elseif (is_multisite()) {
         foreach ($clients as $client_blog_id => $client) {
             if (!$client_blog_id || empty($client->calls)) {
                 continue;
             }
             $switch_success = switch_to_blog($client_blog_id, true);
             if (!$switch_success) {
                 continue;
             }
             flush();
             $client->query();
             restore_current_blog();
         }
     } else {
         if (isset($clients[0]) && !empty($clients[0]->calls)) {
             flush();
             $clients[0]->query();
         }
     }
 }