uawdijnntqw1x1x1
IP : 216.73.216.109
Hostname : premium160.web-hosting.com
Kernel : Linux premium160.web-hosting.com 4.18.0-553.54.1.lve.el8.x86_64 #1 SMP Wed Jun 4 13:01:13 UTC 2025 x86_64
Disable Function : None :)
OS : Linux
PATH:
/
home
/
batcwwjx
/
www
/
wp-content
/
plugins
/
wp-smushit
/
core
/
external
/
hub-connector
/
.
/
inc
/
class-api.php
/
/
<?php /** * The API class. * * @link http://wpmudev.com * @since 1.0.0 * @author Joel James <joel@incsub.com> * @package WPMUDEV\Hub\Connector */ namespace WPMUDEV\Hub\Connector; use WP_Error; /** * Class API */ class API { use Singleton; /** * Check if member is logged in. * * @since 1.0.0 * * @return bool */ public function is_logged_in() { $membership_type = Data::get()->membership_type(); return $this->has_api_key() && ! empty( $membership_type ); } /** * Check if an API key is set. * * @since 1.0.0 * @sice 1.0.6 Added force param. * * @param bool $force Force clear cache. * * @return bool */ public function has_api_key( $force = false ) { $key = $this->get_api_key( $force ); return ! empty( $key ); } /** * Get API key for current member. * * @since 1.0.0 * @sice 1.0.6 Added force param. * * @param bool $force Force clear cache. * * @return string */ public function get_api_key( $force = false ) { if ( defined( '\WPMUDEV_APIKEY' ) && \WPMUDEV_APIKEY ) { return \WPMUDEV_APIKEY; } else { /** * If forced, clear notoptions cache. * * Workaround W3 total Cache, due to possibility of discrepancies where object cache is used/allowed ( wp-admin vs non wp-admin ). * * @see https://incsub.atlassian.net/browse/HUB-10174?focusedCommentId=312567 */ if ( $force ) { if ( defined( 'W3TC' ) ) { if ( is_multisite() ) { $network_id = get_current_network_id(); $cache_key = "$network_id:notoptions"; $cache_group = 'site-options'; } else { $cache_key = 'notoptions'; $cache_group = 'options'; } $notoptions = wp_cache_get( $cache_key, $cache_group ); unset( $notoptions['wpmudev_apikey'] ); wp_cache_set( $cache_key, $notoptions, $cache_group ); wp_cache_delete( 'wpmudev_apikey', $cache_group ); } } do_action( 'wpmudev_hub_connector_before_get_api_key', $force ); // If 'clear_key' is present in URL then do not load the key from DB. return get_site_option( 'wpmudev_apikey', '' ); } } /** * Set API key for current member. * * @since 1.0.0 * * @param string $key API key. * * @return bool */ public function set_api_key( $key ) { return update_site_option( 'wpmudev_apikey', $key ); } /** * Returns the full URL to the specified REST API endpoint. * * @since 1.0.0 * * @param string $endpoint The endpoint to call on the server. * * @return string The full URL to the requested endpoint. */ public function rest_url( $endpoint ) { return Data::get()->server_url( 'api/dashboard/v2/' . $endpoint ); } /** * Returns the full URL to the specified REST API endpoint and includes * the API key as last element in URL. * * Uses the function `rest_url()` to build the URL. * * @since 1.0.0 * * @param string $endpoint The endpoint to call on the server. * * @return string The full URL to the requested endpoint. */ public function rest_url_auth( $endpoint ) { $api_key = $this->get_api_key(); // Append API key. if ( false === strpos( $endpoint, '/' . $api_key ) ) { $endpoint .= '/' . $api_key; } // Get full URL. $url = $this->rest_url( $endpoint ); // Add hub site id if available. $site_id = Data::get()->hub_site_id(); if ( ! empty( $site_id ) ) { $url = add_query_arg( 'site_id', $site_id, $url ); } return $url; } /** * Contacts the API to sync the latest data from this site. * * Returns the membership status if things are working out. * In case the API call fails the function returns boolean false and does * not update the update * * @since 1.0.0 * * @param bool $force Optional forces a sync. * @param bool $auth_check Should check for API key. * * @return array|WP_Error */ public function sync_site( $force = false, $auth_check = true ) { global $wp_version; // Only when logged in. if ( $auth_check && ! $this->has_api_key( $force ) ) { return new WP_Error( 'not_logged_in', __( 'Not logged in.', 'wpmudev' ) ); } // New request object. $request = new Request(); // Last sync timestamp. $last_run = Options::get( 'timestamp_sync', array() ); $data = array( 'call_version' => \WPMUDEV_HUB_CONNECTOR_VERSION, 'domain' => Data::get()->network_site_url(), 'blog_count' => is_multisite() ? get_blog_count() : 1, 'wp_version' => is_multisite() ? "WordPress Multisite $wp_version" : "WordPress $wp_version", 'projects' => wp_json_encode( Data::get()->wpmudev_projects() ), 'admin_url' => Data::get()->network_admin_url(), 'home_url' => Data::get()->network_home_url(), 'sso_status' => false, 'repo_updates' => wp_json_encode( array() ), 'packages' => wp_json_encode( array( 'plugins' => Data::get()->plugins(), 'themes' => Data::get()->themes(), ) ), ); /** * Filter hook to modify final API data. * * @param array $data Data. */ $data = apply_filters( 'wpmudev_hub_connector_get_api_data', $data ); // Get a hash of the data to see if it changed. $data_hash = md5( wp_json_encode( $data ) ); // Clear API cache if forcing an update. if ( $force || empty( $last_run ) ) { $data['call_version'] = microtime( true ); } else { $membership_data = Data::get()->membership_data(); if ( ! empty( $membership_data['membership'] ) ) { // This is the main check to prevent pinging unless the data is changed or 6 hrs have passed. if ( isset( $last_run['hash'], $last_run['time'] ) && $last_run['hash'] === $data_hash && $last_run['time'] > ( time() - ( \HOUR_IN_SECONDS * 6 ) ) ) { $this->maybe_log( '[WPMUDEV API] Skipped sync due to unchanged local data.' ); return $membership_data; } elseif ( $last_run['fails'] ) { // Check for exponential backoff. // 5, 25, 125, 625, 3125, 3600 max. $backoff = min( pow( 5, $last_run['fails'] ), \HOUR_IN_SECONDS ); if ( $last_run['time'] > ( time() - $backoff ) ) { $this->maybe_log( '[WPMUDEV API] Skipped sync due to API error exponential backoff.' ); return $membership_data; } } } } // Make a hub sync request. $response = $request->post( 'hub-sync', true, $data ); // Sync success. if ( 200 === wp_remote_retrieve_response_code( $response ) ) { // Get membership data. $data = json_decode( wp_remote_retrieve_body( $response ), true ); if ( ! empty( $data['membership'] ) ) { // Update membership data. $this->update_membership_data( $data ); // Update sync timestamps. Options::set( 'timestamp_sync', array( 'time' => time(), 'hash' => $data_hash, 'fails' => 0, ) ); $result = $data; } else { return new WP_Error( 'invalid_api_response', __( 'Invalid remote API response.', 'wpmudev' ) ); } } else { // For network errors, perform exponential backoff. Options::set( 'timestamp_sync', array( 'time' => time(), 'fails' => 1, ) ); $api_error = $this->get_api_error( $response ); // Format error messages. $api_error = $this->format_error_messages( $api_error ); return new WP_Error( $api_error['code'], $api_error['message'] ); } /** * Action hook fired after a sync is completed. * * @since 1.0.0 */ do_action( 'wpmudev_hub_connector_sync_completed' ); // If first time sync. if ( empty( $last_run ) ) { /** * Action hook fired after the first sync is completed. * * @since 1.0.0 */ do_action( 'wpmudev_hub_connector_first_sync_completed' ); } return $result; } /** * Logout and disconnect the site from Hub. * * @since 1.0.0 * * @return array|WP_Error */ public function logout() { // Not logged in. if ( ! $this->is_logged_in() ) { return new WP_Error( 'not_logged_in', __( 'Not logged in.', 'wpmudev' ) ); } // Reset settings. Options::reset(); // Remove API key. $this->set_api_key( '' ); // Do a sync to remove site. $sync = $this->sync_site( true, false ); // Handle specific error. if ( is_wp_error( $sync ) && 'invalid_api_response' === $sync->get_error_code() ) { // For logout sync, membership data will be empty. return array(); } return $sync; } /** * Get available teams for the authenticated user. * * This list is used to select the team after login. * * @since 1.0.0 * * @param string $key API key. * * @return array|bool */ public function get_hub_teams( $key ) { $request = new Request(); // Sets up special auth header. $request->add_header_argument( 'Authorization', $key ); // Send API request. $response = $request->get( 'site-authenticate-teams' ); // Error. if ( wp_remote_retrieve_response_code( $response ) !== 200 ) { return false; } else { // Get team list. $data = json_decode( wp_remote_retrieve_body( $response ), true ); if ( isset( $data['data'] ) ) { return $data['data']; } } return array(); } /** * Get the currently logged in member user profile data. * * If not found in db, get it from the API. * * @since 1.0.0 * * @param bool $force Force update from API. * * @return array|WP_Error */ public function get_profile( $force = false ) { // Only when API key is available. if ( ! $this->has_api_key() ) { return new WP_Error( 'not_logged_in', __( 'Not logged in.', 'wpmudev' ) ); } $profile = Options::get( 'profile_data' ); if ( ! empty( $profile ) && ! $force ) { return $profile; } // New request object. $request = new Request(); // Make an API request. $response = $request->get( 'user-info', true ); if ( 200 === wp_remote_retrieve_response_code( $response ) ) { $data = json_decode( wp_remote_retrieve_body( $response ), true ); if ( isset( $data['profile'] ) ) { // Set profile data. Options::set( 'profile_data', $data['profile'] ); return $data['profile']; } else { return new WP_Error( 'api_request_error', __( 'Error unserializing remote response.', 'wpmudev' ) ); } } else { $api_error = $this->get_api_error( $response ); return new WP_Error( $api_error['code'], $api_error['message'] ); } } /** * Parse API error and get a readable error message. * * @since 1.0.0 * * @param mixed $response API response. * * @return array */ private function get_api_error( $response ) { // Default error code is 500. $error_code = wp_remote_retrieve_response_code( $response ); if ( ! $error_code ) { $error_code = 500; } $error = array( 'code' => 'api_error', 'message' => '', ); // Attempt to retrieve http response body. $body = is_array( $response ) ? wp_remote_retrieve_body( $response ) : false; // Get error message. if ( is_scalar( $response ) ) { $error['message'] = $response; } elseif ( is_wp_error( $response ) ) { $error['message'] = $response->get_error_message(); } elseif ( is_array( $response ) && ! empty( $body ) ) { $data = json_decode( wp_remote_retrieve_body( $response ), true ); if ( is_array( $data ) ) { if ( ! empty( $data['message'] ) ) { $error['message'] = $data['message']; } if ( ! empty( $data['code'] ) ) { $error['code'] = $data['code']; } } } $url = '(unknown URL)'; if ( is_array( $response ) && isset( $response['request_url'] ) ) { $url = $response['request_url']; } if ( empty( $error['message'] ) ) { $error['message'] = sprintf( 'HTTP Error: %s "%s"', $error_code, wp_remote_retrieve_response_message( $response ) ); } // Only enabled with constants. // phpcs:disable WordPress.PHP.DevelopmentFunctions.error_log_wp_debug_backtrace_summary // phpcs:disable WordPress.PHP.DevelopmentFunctions.error_log_error_log if ( defined( '\WPMUDEV_API_DEBUG' ) && \WPMUDEV_API_DEBUG ) { $trace = wp_debug_backtrace_summary( null, null, false ); $caller_dump = "\n\t# " . implode( "\n\t# ", $trace ); if ( is_array( $response ) && isset( $response['request_url'] ) ) { $caller_dump = "\n\tURL: " . $response['request_url'] . $caller_dump; } // Log the error to PHP error log. error_log( sprintf( '[WPMUDEV API Error] %s | %s (%s [%s]) %s', \WPMUDEV_HUB_CONNECTOR_VERSION, $error['message'], $url, $error_code, $caller_dump ), 0 ); } // phpcs:enable WordPress.PHP.DevelopmentFunctions.error_log_wp_debug_backtrace_summary // phpcs:enable WordPress.PHP.DevelopmentFunctions.error_log_error_log // If error was "invalid API key" then log out the user. (we don't call logout here to avoid infinite loop). if ( 401 === (int) $error_code && ! defined( '\WPMUDEV_APIKEY' ) && ! defined( '\WPMUDEV_OVERRIDE_LOGOUT' ) ) { $this->set_api_key( '' ); } return $error; } /** * Update membership data from API data. * * @since 1.0.0 * * @param array $data Data to update. * * @return void */ private function update_membership_data( $data ) { if ( isset( $data['membership'] ) && empty( $data['membership'] ) && ! defined( '\WPMUDEV_APIKEY' ) && $this->get_api_key() ) { // Clear API key. $this->set_api_key( '' ); } // Update membership data. Options::set( 'membership_data', $data ); } /** * Write data to error log if log is enabled. * * @since 1.0.0 * * @param string $data Data to log. * * @return void */ private function maybe_log( $data ) { // phpcs:disable WordPress.PHP.DevelopmentFunctions.error_log_error_log // Only if logging is enabled. if ( defined( '\WPMUDEV_API_DEBUG' ) && \WPMUDEV_API_DEBUG ) { error_log( $data ); } // phpcs:enable WordPress.PHP.DevelopmentFunctions.error_log_error_log } /** * Format error messages before showing to public. * * @since 1.0.0 * * @param array $error Error data. * * @return array */ private function format_error_messages( $error ) { // Need both code and message. if ( ! isset( $error['code'], $error['message'] ) ) { return $error; } // Already registered error. if ( 'already_registered' === $error['code'] ) { $error['message'] = sprintf( // translators: %s Support URL. __( 'This site is currently registered to a different user. Please <a target="_blank" href="%s">contact support for assistance</a>.', 'wpmudev' ), Data::get()->server_url( 'hub/support/' ) ); } return $error; } }
/home/batcwwjx/www/wp-content/plugins/wp-smushit/core/external/hub-connector/./inc/class-api.php