| 1 |
<?php |
| 2 |
|
| 3 |
namespace ElementorOne\Admin\Helpers; |
| 4 |
|
| 5 |
use ElementorOne\Admin\Config; |
| 6 |
use ElementorOne\Admin\Services\Client; |
| 7 |
use ElementorOne\Admin\Services\Editor; |
| 8 |
use ElementorOne\Common\SupportedPlugins; |
| 9 |
use ElementorOne\Connect\Classes\GrantTypes; |
| 10 |
use ElementorOne\Connect\Facade; |
| 11 |
use ElementorOne\Versions; |
| 12 |
|
| 13 |
if ( ! defined( 'ABSPATH' ) ) { |
| 14 |
exit; // Exit if accessed directly |
| 15 |
} |
| 16 |
|
| 17 |
/** |
| 18 |
* Class Utils |
| 19 |
*/ |
| 20 |
class Utils { |
| 21 |
|
| 22 |
/** |
| 23 |
* Get API client |
| 24 |
* @return Client|null |
| 25 |
*/ |
| 26 |
public static function get_api_client(): ?Client { |
| 27 |
return Client::instance(); |
| 28 |
} |
| 29 |
|
| 30 |
/** |
| 31 |
* Get ONE connect instance |
| 32 |
* @return Facade |
| 33 |
*/ |
| 34 |
public static function get_one_connect(): Facade { |
| 35 |
return self::get_connect( Config::PLUGIN_SLUG ); |
| 36 |
} |
| 37 |
|
| 38 |
/** |
| 39 |
* Get access token |
| 40 |
* @param string $grant_type |
| 41 |
* @return false|mixed|string|null |
| 42 |
*/ |
| 43 |
public static function get_access_token( string $grant_type = GrantTypes::REFRESH_TOKEN ) { |
| 44 |
return self::get_one_connect()->data()->get_access_token( $grant_type ); |
| 45 |
} |
| 46 |
|
| 47 |
/** |
| 48 |
* Get connect instance |
| 49 |
* @param string $plugin_slug |
| 50 |
* @return Facade|null |
| 51 |
*/ |
| 52 |
public static function get_connect( string $plugin_slug = Config::PLUGIN_SLUG ): ?Facade { |
| 53 |
return Facade::get( $plugin_slug ); |
| 54 |
} |
| 55 |
|
| 56 |
/** |
| 57 |
* Check if plugin is connected |
| 58 |
* @param string $plugin_slug |
| 59 |
* @return bool |
| 60 |
*/ |
| 61 |
public static function is_plugin_connected( string $plugin_slug ): bool { |
| 62 |
$facade = self::get_connect( $plugin_slug ); |
| 63 |
|
| 64 |
if ( $facade && $facade->utils()->is_connected() ) { |
| 65 |
return true; |
| 66 |
} |
| 67 |
|
| 68 |
// Fallback to license key check for Elementor Pro |
| 69 |
return SupportedPlugins::ELEMENTOR_PRO === $plugin_slug |
| 70 |
&& (bool) Editor::get_active_license_key( $plugin_slug ); |
| 71 |
} |
| 72 |
|
| 73 |
/** |
| 74 |
* Get package version |
| 75 |
* @param string $plugin_slug |
| 76 |
* @return string|null |
| 77 |
*/ |
| 78 |
public static function get_package_version( string $plugin_slug ): ?string { |
| 79 |
global $wp_one_package_versions; |
| 80 |
$plugin_slug = self::filter_plugin_slug( $plugin_slug ); |
| 81 |
return $wp_one_package_versions[ $plugin_slug ] ?? null; |
| 82 |
} |
| 83 |
|
| 84 |
/** |
| 85 |
* Get latest package version |
| 86 |
* @return string|null |
| 87 |
*/ |
| 88 |
public static function get_latest_package_version(): ?string { |
| 89 |
return Versions::instance()->latest_version(); |
| 90 |
} |
| 91 |
|
| 92 |
/** |
| 93 |
* Get plugin data |
| 94 |
* @param string $plugin_slug |
| 95 |
* @return array|null |
| 96 |
*/ |
| 97 |
public static function get_plugin_data( string $plugin_slug ): ?array { |
| 98 |
$plugin_slug = self::filter_plugin_slug( $plugin_slug ); |
| 99 |
|
| 100 |
foreach ( get_plugins() as $plugin_file => $plugin_data ) { |
| 101 |
if ( preg_match( '~^' . preg_quote( $plugin_slug, '~' ) . '/~', $plugin_file ) === 1 ) { |
| 102 |
$plugin_data['_file'] = $plugin_file; |
| 103 |
return $plugin_data; |
| 104 |
} |
| 105 |
} |
| 106 |
|
| 107 |
return null; |
| 108 |
} |
| 109 |
|
| 110 |
/** |
| 111 |
* Get plugin slug |
| 112 |
* @param string $plugin_slug |
| 113 |
* @return string |
| 114 |
*/ |
| 115 |
public static function filter_plugin_slug( string $plugin_slug ): string { |
| 116 |
return apply_filters( 'elementor_one/plugin_slug', $plugin_slug ); |
| 117 |
} |
| 118 |
|
| 119 |
/** |
| 120 |
* Get plugin new version |
| 121 |
* @param string $plugin_file |
| 122 |
* @return string|null |
| 123 |
*/ |
| 124 |
public static function get_plugin_new_version( string $plugin_file, ?\stdClass $plugin_updates = null ): ?string { |
| 125 |
if ( is_null( $plugin_updates ) ) { |
| 126 |
wp_update_plugins(); |
| 127 |
$plugin_updates = get_site_transient( 'update_plugins' ); |
| 128 |
} |
| 129 |
return $plugin_updates->response[ $plugin_file ]->new_version ?? null; |
| 130 |
} |
| 131 |
|
| 132 |
/** |
| 133 |
* Convert camel case to snake case |
| 134 |
* @param string $input |
| 135 |
* @return string |
| 136 |
*/ |
| 137 |
public static function camel_to_snake( string $input ): string { |
| 138 |
return strtolower( |
| 139 |
preg_replace( '/(?<!^)[A-Z]/', '_$0', $input ) |
| 140 |
); |
| 141 |
} |
| 142 |
|
| 143 |
/** |
| 144 |
* Get authorize URL |
| 145 |
* @return string |
| 146 |
*/ |
| 147 |
public static function get_authorize_url(): ?string { |
| 148 |
$facade = self::get_one_connect(); |
| 149 |
$client_id = $facade->data()->get_client_id(); |
| 150 |
|
| 151 |
if ( ! $client_id ) { |
| 152 |
try { |
| 153 |
$client_id = $facade->service()->register_client(); |
| 154 |
} catch ( \Throwable $_th ) { |
| 155 |
return null; |
| 156 |
} |
| 157 |
} |
| 158 |
|
| 159 |
return $facade->utils()->get_authorize_url( $client_id ); |
| 160 |
} |
| 161 |
|
| 162 |
/** |
| 163 |
* Decode JWT and return payload without signature verification |
| 164 |
* @param string $jwt |
| 165 |
* @return array|null |
| 166 |
*/ |
| 167 |
public static function decode_jwt( string $jwt ): ?array { |
| 168 |
$parts = explode( '.', $jwt ); |
| 169 |
|
| 170 |
if ( count( $parts ) !== 3 ) { |
| 171 |
return null; |
| 172 |
} |
| 173 |
|
| 174 |
$payload = base64_decode( strtr( $parts[1], '-_', '+/' ) ); |
| 175 |
|
| 176 |
if ( ! $payload ) { |
| 177 |
return null; |
| 178 |
} |
| 179 |
|
| 180 |
$decoded = json_decode( $payload, true ); |
| 181 |
|
| 182 |
return is_array( $decoded ) ? $decoded : null; |
| 183 |
} |
| 184 |
|
| 185 |
/** |
| 186 |
* Check if JWT token is expired |
| 187 |
* @param string $jwt |
| 188 |
* @param int $buffer Buffer in seconds to account for clock skew |
| 189 |
* @return bool |
| 190 |
*/ |
| 191 |
public static function is_jwt_expired( string $jwt, int $buffer = 30 ): bool { |
| 192 |
$jwt_payload = self::decode_jwt( $jwt ); |
| 193 |
if ( $jwt_payload && isset( $jwt_payload['exp'] ) ) { |
| 194 |
return ( time() + $buffer ) >= $jwt_payload['exp']; |
| 195 |
} |
| 196 |
return false; |
| 197 |
} |
| 198 |
} |
| 199 |
|