Edit File by line
/home/zeestwma/ajeebong.../wp-conte.../plugins/image-op.../modules/oauth/componen...
File: connect.php
<?php
[0] Fix | Delete
[1] Fix | Delete
namespace ImageOptimization\Modules\Oauth\Components;
[2] Fix | Delete
[3] Fix | Delete
use ImageOptimization\Modules\Oauth\{
[4] Fix | Delete
Classes\Route_Base,
[5] Fix | Delete
Components\Exceptions\Auth_Error,
[6] Fix | Delete
Classes\Data,
[7] Fix | Delete
};
[8] Fix | Delete
use ImageOptimization\Classes\Logger;
[9] Fix | Delete
use ImageOptimization\Classes\Utils;
[10] Fix | Delete
use ImageOptimization\Modules\Settings\Module as Settings_Module;
[11] Fix | Delete
[12] Fix | Delete
use stdClass;
[13] Fix | Delete
use Throwable;
[14] Fix | Delete
[15] Fix | Delete
if ( ! defined( 'ABSPATH' ) ) {
[16] Fix | Delete
exit; // Exit if accessed directly.
[17] Fix | Delete
}
[18] Fix | Delete
[19] Fix | Delete
/**
[20] Fix | Delete
* Class Connect
[21] Fix | Delete
*/
[22] Fix | Delete
class Connect {
[23] Fix | Delete
const API_URL = 'https://my.elementor.com/api/connect/v1';
[24] Fix | Delete
const STATUS_CHECK_TRANSIENT = 'image_optimizer_status_check';
[25] Fix | Delete
[26] Fix | Delete
/**
[27] Fix | Delete
* is_connected
[28] Fix | Delete
* @return bool
[29] Fix | Delete
*/
[30] Fix | Delete
public static function is_connected(): bool {
[31] Fix | Delete
return ! empty( Data::get_connect_data()['access_token'] );
[32] Fix | Delete
}
[33] Fix | Delete
[34] Fix | Delete
/**
[35] Fix | Delete
* is_activated
[36] Fix | Delete
* @return bool
[37] Fix | Delete
*/
[38] Fix | Delete
public static function is_activated(): bool {
[39] Fix | Delete
return ! empty( Data::get_activation_state() );
[40] Fix | Delete
}
[41] Fix | Delete
[42] Fix | Delete
/**
[43] Fix | Delete
* maybe_handle_admin_connect_page
[44] Fix | Delete
* @return bool
[45] Fix | Delete
*/
[46] Fix | Delete
public static function maybe_handle_admin_connect_page(): bool {
[47] Fix | Delete
if ( ! isset( $_GET['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['nonce'] ) ), 'nonce_actionget_token' ) ) {
[48] Fix | Delete
return false;
[49] Fix | Delete
}
[50] Fix | Delete
[51] Fix | Delete
$args = [
[52] Fix | Delete
'page' => 'elementor-connect',
[53] Fix | Delete
'app' => 'library',
[54] Fix | Delete
'action' => 'get_token',
[55] Fix | Delete
'state' => Data::get_connect_state(),
[56] Fix | Delete
];
[57] Fix | Delete
[58] Fix | Delete
foreach ( $args as $key => $value ) {
[59] Fix | Delete
if ( ! isset( $_GET[ $key ] ) || $_GET[ $key ] !== $value ) {
[60] Fix | Delete
return false;
[61] Fix | Delete
}
[62] Fix | Delete
}
[63] Fix | Delete
[64] Fix | Delete
if ( ! isset( $_GET['nonce'] ) || ! isset( $_GET['code'] ) ) {
[65] Fix | Delete
return false;
[66] Fix | Delete
}
[67] Fix | Delete
[68] Fix | Delete
return true;
[69] Fix | Delete
}
[70] Fix | Delete
[71] Fix | Delete
/**
[72] Fix | Delete
* handle_elementor_connect_admin
[73] Fix | Delete
*/
[74] Fix | Delete
public function handle_elementor_connect_admin(): void {
[75] Fix | Delete
// validate args
[76] Fix | Delete
if ( ! self::maybe_handle_admin_connect_page() ) {
[77] Fix | Delete
return;
[78] Fix | Delete
}
[79] Fix | Delete
[80] Fix | Delete
// validate nonce
[81] Fix | Delete
if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['nonce'] ) ), 'nonce_actionget_token' ) ) {
[82] Fix | Delete
wp_die( 'Nonce verification failed', 'image-optimization' );
[83] Fix | Delete
}
[84] Fix | Delete
[85] Fix | Delete
$token_response = wp_remote_request( self::API_URL . '/get_token', [
[86] Fix | Delete
'method' => 'POST',
[87] Fix | Delete
'body' => [
[88] Fix | Delete
'app' => 'library',
[89] Fix | Delete
'grant_type' => 'authorization_code',
[90] Fix | Delete
'client_id' => Data::get_client_id(),
[91] Fix | Delete
'code' => sanitize_text_field( $_GET['code'] ),
[92] Fix | Delete
],
[93] Fix | Delete
] );
[94] Fix | Delete
[95] Fix | Delete
if ( is_wp_error( $token_response ) ) {
[96] Fix | Delete
wp_die( $token_response->get_error_message(), 'image-optimization' );
[97] Fix | Delete
}
[98] Fix | Delete
[99] Fix | Delete
$data = json_decode( wp_remote_retrieve_body( $token_response ), true );
[100] Fix | Delete
Data::set_connect_data( $data );
[101] Fix | Delete
[102] Fix | Delete
do_action( Checkpoint::ON_CONNECT );
[103] Fix | Delete
[104] Fix | Delete
// cleanup
[105] Fix | Delete
Data::delete_connect_state();
[106] Fix | Delete
[107] Fix | Delete
wp_redirect( add_query_arg( [
[108] Fix | Delete
'page' => Settings_Module::SETTING_BASE_SLUG,
[109] Fix | Delete
'connected' => 'true',
[110] Fix | Delete
], admin_url( 'admin.php' ) ) );
[111] Fix | Delete
die();
[112] Fix | Delete
}
[113] Fix | Delete
[114] Fix | Delete
/**
[115] Fix | Delete
* Gets required connection data from the service and generates a connect link.
[116] Fix | Delete
*
[117] Fix | Delete
* @return string User connect link
[118] Fix | Delete
*
[119] Fix | Delete
* @throws Auth_Error
[120] Fix | Delete
*/
[121] Fix | Delete
public static function initialize_connect(): string {
[122] Fix | Delete
try {
[123] Fix | Delete
$response = wp_remote_request(
[124] Fix | Delete
self::API_URL . '/library/get_client_id',
[125] Fix | Delete
[
[126] Fix | Delete
'method' => 'POST',
[127] Fix | Delete
'body' => [
[128] Fix | Delete
'local_id' => get_current_user_id(),
[129] Fix | Delete
'site_key' => Data::get_site_key(),
[130] Fix | Delete
'app' => 'library',
[131] Fix | Delete
'home_url' => trailingslashit( home_url() ),
[132] Fix | Delete
'source' => 'image-optimizer',
[133] Fix | Delete
],
[134] Fix | Delete
]
[135] Fix | Delete
);
[136] Fix | Delete
} catch ( Throwable $t ) {
[137] Fix | Delete
Logger::log(
[138] Fix | Delete
Logger::LEVEL_ERROR,
[139] Fix | Delete
'Error while sending connection initialization request: ' . $t->getMessage()
[140] Fix | Delete
);
[141] Fix | Delete
[142] Fix | Delete
throw new Auth_Error( $t->getMessage() );
[143] Fix | Delete
}
[144] Fix | Delete
[145] Fix | Delete
$data = json_decode( wp_remote_retrieve_body( $response ) );
[146] Fix | Delete
[147] Fix | Delete
if ( ! isset( $data->client_id ) || ! isset( $data->auth_secret ) ) {
[148] Fix | Delete
Logger::log(
[149] Fix | Delete
Logger::LEVEL_ERROR,
[150] Fix | Delete
'Invalid response from server: client id or auth secret are undefined'
[151] Fix | Delete
);
[152] Fix | Delete
[153] Fix | Delete
throw new Auth_Error( esc_html__( 'Invalid response from server', 'image-optimization' ) );
[154] Fix | Delete
}
[155] Fix | Delete
[156] Fix | Delete
Data::set_client_data( $data->client_id, $data->auth_secret );
[157] Fix | Delete
[158] Fix | Delete
return add_query_arg( [
[159] Fix | Delete
'utm_source' => 'image-optimizer-panel',
[160] Fix | Delete
'utm_campaign' => 'image-optimizer',
[161] Fix | Delete
'utm_medium' => 'wp-dash',
[162] Fix | Delete
'source' => 'generic',
[163] Fix | Delete
'action' => 'authorize',
[164] Fix | Delete
'response_type' => 'code',
[165] Fix | Delete
'client_id' => $data->client_id,
[166] Fix | Delete
'auth_secret' => $data->auth_secret,
[167] Fix | Delete
'state' => Data::get_connect_state( true ),
[168] Fix | Delete
'redirect_uri' => rawurlencode( add_query_arg( [
[169] Fix | Delete
'page' => 'elementor-connect',
[170] Fix | Delete
'app' => 'library',
[171] Fix | Delete
'action' => 'get_token',
[172] Fix | Delete
'nonce' => wp_create_nonce( 'nonce_action' . 'get_token' ),
[173] Fix | Delete
], admin_url( 'admin.php' ) ) ),
[174] Fix | Delete
'may_share_data' => 0,
[175] Fix | Delete
'reconnect_nonce' => wp_create_nonce( 'nonce_action' . 'reconnect' ),
[176] Fix | Delete
], Route_Base::SITE_URL . 'library' );
[177] Fix | Delete
}
[178] Fix | Delete
[179] Fix | Delete
/**
[180] Fix | Delete
* Disconnects a user and removes connection data from the DB.
[181] Fix | Delete
*/
[182] Fix | Delete
public static function disconnect() {
[183] Fix | Delete
do_action( Checkpoint::ON_DISCONNECT );
[184] Fix | Delete
[185] Fix | Delete
try {
[186] Fix | Delete
return wp_remote_request( self::API_URL . '/disconnect', [
[187] Fix | Delete
'method' => 'POST',
[188] Fix | Delete
'body' => [
[189] Fix | Delete
'app' => 'library',
[190] Fix | Delete
'home_url' => trailingslashit( home_url() ),
[191] Fix | Delete
'client_id' => Data::get_client_id(),
[192] Fix | Delete
'access_token' => Data::get_access_token(),
[193] Fix | Delete
],
[194] Fix | Delete
] );
[195] Fix | Delete
} catch ( Throwable $t ) {
[196] Fix | Delete
Logger::log( Logger::LEVEL_ERROR, 'Error while sending disconnection request: ' . $t->getMessage() );
[197] Fix | Delete
[198] Fix | Delete
throw new Auth_Error( $t->getMessage() );
[199] Fix | Delete
} finally {
[200] Fix | Delete
Data::reset();
[201] Fix | Delete
}
[202] Fix | Delete
}
[203] Fix | Delete
[204] Fix | Delete
/**
[205] Fix | Delete
* Sends an activation request and stores activation data in the DB.
[206] Fix | Delete
*
[207] Fix | Delete
* @param $license_key string License key to activate with.
[208] Fix | Delete
* @return mixed
[209] Fix | Delete
*
[210] Fix | Delete
* @throws Auth_Error
[211] Fix | Delete
*/
[212] Fix | Delete
public static function activate( string $license_key ) {
[213] Fix | Delete
try {
[214] Fix | Delete
$response = Utils::get_api_client()->make_request(
[215] Fix | Delete
'POST',
[216] Fix | Delete
'activation/activate',
[217] Fix | Delete
[],
[218] Fix | Delete
[ 'key' => $license_key ]
[219] Fix | Delete
);
[220] Fix | Delete
} catch ( Throwable $t ) {
[221] Fix | Delete
Logger::log( Logger::LEVEL_ERROR, 'Error while sending activation request: ' . $t->getMessage() );
[222] Fix | Delete
[223] Fix | Delete
throw new Auth_Error( $t->getMessage() );
[224] Fix | Delete
}
[225] Fix | Delete
[226] Fix | Delete
if ( ! isset( $response->id ) ) {
[227] Fix | Delete
Logger::log( Logger::LEVEL_ERROR, 'Invalid response from server' );
[228] Fix | Delete
[229] Fix | Delete
throw new Auth_Error( esc_html__( 'Invalid response from server', 'image-optimization' ) );
[230] Fix | Delete
}
[231] Fix | Delete
[232] Fix | Delete
Data::set_activation_state( $license_key );
[233] Fix | Delete
[234] Fix | Delete
do_action( Checkpoint::ON_ACTIVATE, $license_key );
[235] Fix | Delete
[236] Fix | Delete
return $response;
[237] Fix | Delete
}
[238] Fix | Delete
[239] Fix | Delete
/**
[240] Fix | Delete
* Deactivate specific license and remove activation data from the DB.
[241] Fix | Delete
*
[242] Fix | Delete
* @param $license_key string License key to deactivate.
[243] Fix | Delete
*
[244] Fix | Delete
* @return mixed
[245] Fix | Delete
*
[246] Fix | Delete
* @throws Auth_Error
[247] Fix | Delete
*/
[248] Fix | Delete
public static function deactivate( string $license_key ) {
[249] Fix | Delete
[250] Fix | Delete
do_action( Checkpoint::ON_DEACTIVATE, $license_key );
[251] Fix | Delete
[252] Fix | Delete
try {
[253] Fix | Delete
$response = Utils::get_api_client()->make_request(
[254] Fix | Delete
'POST',
[255] Fix | Delete
'activation/deactivate',
[256] Fix | Delete
[
[257] Fix | Delete
'key' => $license_key,
[258] Fix | Delete
]
[259] Fix | Delete
);
[260] Fix | Delete
} catch ( Throwable $t ) {
[261] Fix | Delete
Logger::log( Logger::LEVEL_ERROR, 'Error while sending deactivation request: ' . $t->getMessage() );
[262] Fix | Delete
[263] Fix | Delete
throw new Auth_Error( $t->getMessage() );
[264] Fix | Delete
} finally {
[265] Fix | Delete
Data::delete_activation_state();
[266] Fix | Delete
}
[267] Fix | Delete
[268] Fix | Delete
if ( ! isset( $response->id ) ) {
[269] Fix | Delete
Logger::log( Logger::LEVEL_ERROR, 'Invalid response from server' );
[270] Fix | Delete
[271] Fix | Delete
throw new Auth_Error( esc_html__( 'Invalid response from server', 'image-optimization' ) );
[272] Fix | Delete
}
[273] Fix | Delete
[274] Fix | Delete
return $response;
[275] Fix | Delete
}
[276] Fix | Delete
[277] Fix | Delete
/**
[278] Fix | Delete
* Fetches and returns a list of available licenses for a specific user.
[279] Fix | Delete
*
[280] Fix | Delete
* @return array Available subscriptions or an empty array
[281] Fix | Delete
*
[282] Fix | Delete
* @throws Auth_Error
[283] Fix | Delete
*/
[284] Fix | Delete
public static function get_subscriptions(): array {
[285] Fix | Delete
try {
[286] Fix | Delete
$response = Utils::get_api_client()->make_request(
[287] Fix | Delete
'POST',
[288] Fix | Delete
'activation/get-subscriptions'
[289] Fix | Delete
);
[290] Fix | Delete
} catch ( Throwable $t ) {
[291] Fix | Delete
Logger::log( Logger::LEVEL_ERROR, 'Error while fetching subscriptions: ' . $t->getMessage() );
[292] Fix | Delete
[293] Fix | Delete
throw new Auth_Error( $t->getMessage() );
[294] Fix | Delete
}
[295] Fix | Delete
[296] Fix | Delete
if ( ! isset( $response->subscriptions ) ) {
[297] Fix | Delete
Logger::log( Logger::LEVEL_ERROR, 'Invalid response from server' );
[298] Fix | Delete
[299] Fix | Delete
throw new Auth_Error( esc_html__( 'Invalid response from server', 'image-optimization' ) );
[300] Fix | Delete
}
[301] Fix | Delete
[302] Fix | Delete
return $response->subscriptions;
[303] Fix | Delete
}
[304] Fix | Delete
[305] Fix | Delete
public static function get_connect_status() {
[306] Fix | Delete
if ( ! self::is_connected() ) {
[307] Fix | Delete
Logger::log( Logger::LEVEL_INFO, 'Status getting error. Reason: User is not connected' );
[308] Fix | Delete
[309] Fix | Delete
return null;
[310] Fix | Delete
}
[311] Fix | Delete
[312] Fix | Delete
$cached_status = get_transient( self::STATUS_CHECK_TRANSIENT );
[313] Fix | Delete
[314] Fix | Delete
if ( $cached_status ) {
[315] Fix | Delete
return $cached_status;
[316] Fix | Delete
}
[317] Fix | Delete
[318] Fix | Delete
$status = self::check_connect_status();
[319] Fix | Delete
[320] Fix | Delete
set_transient( self::STATUS_CHECK_TRANSIENT, $status, MINUTE_IN_SECONDS * 5 );
[321] Fix | Delete
[322] Fix | Delete
return $status;
[323] Fix | Delete
}
[324] Fix | Delete
[325] Fix | Delete
private static function check_connect_status() {
[326] Fix | Delete
if ( ! self::is_connected() ) {
[327] Fix | Delete
Logger::log( Logger::LEVEL_INFO, 'Status check error. Reason: User is not connected' );
[328] Fix | Delete
[329] Fix | Delete
return null;
[330] Fix | Delete
}
[331] Fix | Delete
[332] Fix | Delete
try {
[333] Fix | Delete
$response = Utils::get_api_client()->make_request(
[334] Fix | Delete
'POST',
[335] Fix | Delete
'status/check'
[336] Fix | Delete
);
[337] Fix | Delete
} catch ( Throwable $t ) {
[338] Fix | Delete
Logger::log(
[339] Fix | Delete
Logger::LEVEL_ERROR,
[340] Fix | Delete
'Status check error. Reason: ' . $t->getMessage()
[341] Fix | Delete
);
[342] Fix | Delete
[343] Fix | Delete
return null;
[344] Fix | Delete
}
[345] Fix | Delete
[346] Fix | Delete
if ( ! isset( $response->status ) ) {
[347] Fix | Delete
Logger::log( Logger::LEVEL_ERROR, 'Invalid response from server' );
[348] Fix | Delete
[349] Fix | Delete
return null;
[350] Fix | Delete
}
[351] Fix | Delete
[352] Fix | Delete
return $response;
[353] Fix | Delete
}
[354] Fix | Delete
[355] Fix | Delete
public static function update_usage_data( stdClass $new_usage_data ) {
[356] Fix | Delete
$connect_status = self::get_connect_status();
[357] Fix | Delete
[358] Fix | Delete
if ( ! isset( $new_usage_data->allowed ) || ! isset( $new_usage_data->used ) ) {
[359] Fix | Delete
return;
[360] Fix | Delete
}
[361] Fix | Delete
[362] Fix | Delete
if ( 0 === $new_usage_data->allowed - $new_usage_data->used ) {
[363] Fix | Delete
$connect_status->status = 'expired';
[364] Fix | Delete
}
[365] Fix | Delete
[366] Fix | Delete
$connect_status->quota = $new_usage_data->allowed;
[367] Fix | Delete
$connect_status->used_quota = $new_usage_data->used;
[368] Fix | Delete
[369] Fix | Delete
set_transient( self::STATUS_CHECK_TRANSIENT, $connect_status, MINUTE_IN_SECONDS * 5 );
[370] Fix | Delete
}
[371] Fix | Delete
[372] Fix | Delete
public function __construct() {
[373] Fix | Delete
// handle connect if elementor is active
[374] Fix | Delete
add_action( 'load-elementor_page_elementor-connect', [ $this, 'handle_elementor_connect_admin' ], 9 );
[375] Fix | Delete
// handle connect if elementor is not active
[376] Fix | Delete
add_action( '_admin_menu', [ $this, 'handle_elementor_connect_admin' ] );
[377] Fix | Delete
}
[378] Fix | Delete
}
[379] Fix | Delete
[380] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function