Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
File Manager
/
wp-content
/
plugins
/
elementor
/
vendor
/
elementor
/
wp-one-package
/
src
/
Admin
/
Services
:
Client.php
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<?php namespace ElementorOne\Admin\Services; use ElementorOne\Admin\Config; use ElementorOne\Admin\Exceptions\ClientException; use ElementorOne\Admin\Helpers\Utils; use ElementorOne\Connect\Classes\GrantTypes; use ElementorOne\Logger; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly } /** * Class Client */ class Client { const BASE_URL = 'https://my.elementor.com'; /** * Logger instance * @var Logger */ private Logger $logger; /** * Instance * @var Client|null */ private static ?Client $instance = null; /** * Get instance * @return Client|null */ public static function instance(): ?Client { if ( ! self::$instance ) { self::$instance = new self(); } return self::$instance; } /** * Constructor */ private function __construct() { $this->logger = new Logger( self::class ); } /** * Refreshed flag * @var bool */ private bool $refreshed = false; /** * Check if JWT token is expired * @param string $token * @return bool */ private function token_expired( string $token ): bool { try { $payload = Utils::decode_jwt( $token ); if ( ! isset( $payload['exp'] ) ) { return false; // No expiration claim, let the regular flow handle it } // Check if token is expired (with 60 second buffer to account for clock skew) return ( $payload['exp'] - MINUTE_IN_SECONDS ) < time(); } catch ( \Throwable $th ) { $this->logger->error( 'Error checking token expiration: ' . $th->getMessage() ); return false; // On error, let the regular flow handle it } } /** * Refresh access token * @param string $grant_type * @return self * @throws ClientException */ private function refresh_access_token( string $grant_type ): self { $this->refreshed = true; try { Utils::get_one_connect()->service()->renew_access_token( $grant_type ); } catch ( \Throwable $th ) { throw new ClientException( $th->getMessage(), \WP_Http::UNAUTHORIZED ); } return $this; } /** * Request * @param string $url * @param array $args * @param int $valid_response_code * @return mixed * @throws ClientException */ public function request( string $url, array $args, ?callable $callback = null, string $grant_type = GrantTypes::REFRESH_TOKEN, int $valid_response_code = \WP_Http::OK ) { $access_token = Utils::get_access_token( $grant_type ); // Decode and check token expiration if ( ! $this->refreshed && $this->token_expired( $access_token ) ) { $this->refresh_access_token( $grant_type ); $access_token = Utils::get_access_token( $grant_type ); } $args['timeout'] = 30; $args['headers'] = array_merge( $args['headers'] ?? [], [ 'Content-Type' => 'application/json', 'Authorization' => "Bearer {$access_token}", 'x-elementor-app-type' => Config::APP_TYPE, ] ); $response = wp_remote_request( $url, $args ); // If the response is an error, throw an error. if ( is_wp_error( $response ) ) { $this->logger->error( $response->get_error_message() ); throw new ClientException( $response->get_error_message() ); } $response_body = wp_remote_retrieve_body( $response ); $response_code = wp_remote_retrieve_response_code( $response ); // If the response body is not valid, throw an error. if ( ! empty( $response_body ) && null === json_decode( $response_body ) ) { throw new ClientException( esc_html( $response_body ), $response_code ); } // If the token is invalid, refresh it and try again once only. if ( ! $this->refreshed && \WP_Http::UNAUTHORIZED === $response_code ) { return $this->refresh_access_token( $grant_type ) ->request( $url, $args, $callback, $grant_type, $valid_response_code ); } // If the response code is not valid, throw an error. if ( $response_code !== $valid_response_code ) { $this->logger->error( 'Invalid status code ' . wp_remote_retrieve_response_code( $response ) ); throw new ClientException( json_decode( $response_body )->message ?? $response_body, $response_code ); } // If a callback is provided, call it. if ( $callback ) { return call_user_func( $callback, $response_body ); } return json_decode( $response_body, true ); } /** * Get client base URL * @return string */ public static function get_client_base_url() { return apply_filters( 'elementor_one/get_client_base_url', self::BASE_URL ); } }