username = sanitize_text_field( $username ); $this->api_key = sanitize_text_field( $api_key ); } /** * Decorate a payload array with common data. * * @since 3.10 * * @param array $payload * * @return array */ protected function _get_decorated_payload( $payload ) { if ( ! isset( $payload['username'] ) ) { $payload['username'] = $this->username; } if ( ! isset( $payload['api_key'] ) ) { $payload['api_key'] = $this->api_key; } return $payload; } /** * Decorate request options array with common options. * * @since 3.10 * * @param array $options * * @return array */ protected function _get_decorated_request_options( $options = array() ) { global $wp_version; $options = array_merge( array( 'timeout' => 30, 'user-agent' => 'WordPress/' . $wp_version . '; ' . home_url( '/' ), ), $options ); return $options; } /** * Parse a response from the API. * * @since 3.10 * * @param array|WP_Error $response * * @return object|WP_Error */ protected function _parse_response( $response ) { if ( is_wp_error( $response ) ) { return $response; } $response_body = trim( wp_remote_retrieve_body( $response ) ); if ( '' === $response_body ) { return new WP_Error( 'et_unknown', esc_html__( 'An unknown error has occurred. Please try again later.', 'et-core' ) ); } $credentials_errors = array( 'Username is not set.', 'Subscription is not active', ); if ( in_array( $response_body, $credentials_errors ) ) { return new WP_Error( 'et_invalid_api_credentials', esc_html__( 'Invalid Username and/or API Key provided.', 'et-core' ) ); } return maybe_unserialize( $response_body ); } /** * Get the full API endpoint. * * @since 3.10 * * @param string $endpoint "api" or "api_downloads" * * @return string */ protected function _get_endpoint( $endpoint = 'api' ) { $allowed_endpoints = array( 'api', 'api_downloads' ); $suffix = '.php'; if ( ! in_array( $endpoint, $allowed_endpoints ) ) { $endpoint = $allowed_endpoints[0]; } return esc_url_raw( $this->api_url . $endpoint . $suffix ); } /** * Submit a GET request to the API. * * @since 3.10 * * @param array $payload * @param string $endpoint * * @return object|WP_Error */ protected function _get( $payload, $endpoint = 'api' ) { $payload = $this->_get_decorated_payload( $payload ); $options = $this->_get_decorated_request_options(); $url = esc_url_raw( add_query_arg( $payload, $this->_get_endpoint( $endpoint ) ) ); $response = wp_remote_get( $url, $options ); return $this->_parse_response( $response ); } /** * Submit a POST request to the API. * * @since 3.10 * * @param array $payload * @param string $endpoint * * @return object|WP_Error */ protected function _post( $payload, $endpoint = 'api' ) { $payload = $this->_get_decorated_payload( $payload ); $options = $this->_get_decorated_request_options( array( 'body' => $payload, ) ); $response = wp_remote_post( $this->_get_endpoint( $endpoint ), $options ); return $this->_parse_response( $response ); } /** * Check if a product is available. * * @since 3.10 * * @param string $product_name * @param string $version * * @return bool|WP_Error */ public function is_product_available( $product_name, $version ) { $response = $this->_get( array( 'api_update' => 1, 'action' => 'check_version_status', 'product' => $product_name, 'version' => $version, ) ); if ( is_wp_error( $response ) ) { return $response; } if ( ! is_array( $response ) ) { return new WP_Error( 'et_unknown', esc_html__( 'An unexpected response was received from the version server. Please try again later.', 'et-core' ) ); } switch ( $response['status'] ) { case 'not_available': return new WP_Error( 'et_version_rollback_not_available', sprintf( esc_html__( 'The previously used version of %1$s does not support version rollback.', 'et-core' ), esc_html( $product_name ) ) ); case 'blocklisted': return new WP_Error( 'et_version_rollback_blocklisted', et_get_safe_localization( sprintf( __( 'For privacy and security reasons, you cannot rollback to Version %1$s.', 'et-core' ), esc_html( $version ) ) ) ); case 'available': return true; } return new WP_Error( 'et_unknown', esc_html__( 'An unknown error has occurred. Please try again later.', 'et-core' ) ); } /** * Get a product download url for a specific version, if available. * * @since 3.10 * * @param string $product_name * @param string $version * * @return string|WP_Error */ public function get_download_url( $product_name, $version ) { $payload = $this->_get_decorated_payload( array( 'api_update' => 1, 'theme' => $product_name, 'version' => $version, ) ); return esc_url_raw( add_query_arg( $payload, $this->_get_endpoint( 'api_downloads' ) ) ); } } endif;