PluginProbe
Image Optimizer – Compress Images and Convert to WebP or AVIF / 1.7.7
Image Optimizer – Compress Images and Convert to WebP or AVIF v1.7.7
1.7.7 1.7.6 1.7.5 1.7.4 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.2.0 1.2.1 1.3.0 1.4.0 1.4.1 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 All 33 releases
← All changes | classes/client/client.php +54 -19 1.6.31.7.7 View file →
@@ -5,8 +5,10 @@
5 5 use ImageOptimization\Classes\Exceptions\Client_Exception;
6 6 use ImageOptimization\Classes\File_Utils;
7 7 use ImageOptimization\Classes\Image\Image;
8 8 use ImageOptimization\Classes\Logger;
9 +use ImageOptimization\Modules\Connect\Module as Connect_Module;
10 +use ImageOptimization\Modules\Optimization\Classes\Optimize_Image;
9 11 use ImageOptimization\Modules\Stats\Classes\Optimization_Stats;
10 12 use Throwable;
11 13 use WP_Error;
12 14
@@ -20,13 +22,14 @@
20 22 * Class Client
21 23 */
22 24 class Client {
23 25 const BASE_URL = 'https://my.elementor.com/api/v2/image-optimizer/';
24 - const STATUS_CHECK = 'status/check';
26 + const BASE_URL_FEEDBACK = 'https://feedback-api.prod.apps.elementor.red/apps/api/v1/';
25 27 const SITE_INFO = 'site/info';
26 - const SITE_INFO_TRANSIENT = 'image_optimizer_site_info_transient';
28 + const SITE_INFO_TRANSIENT = 'image_optimizer_site_info';
29 + const SITE_INFO_TRANSIENT_ERROR = 'image_optimizer_site_info_error';
30 + const ERROR_CACHE_DURATION = MINUTE_IN_SECONDS * 5;
27 31
28 -
29 32 private bool $refreshed = false;
30 33
31 34 public static ?Client $instance = null;
32 35
@@ -37,8 +40,9 @@
37 40 public static function get_instance(): ?Client {
38 41 if ( ! self::$instance ) {
39 42 self::$instance = new self();
40 43 }
44 +
41 45 return self::$instance;
42 46 }
43 47
44 48 public static function get_site_info( $endpoint = null ): array {
@@ -53,9 +57,9 @@
53 57 'local_id' => get_current_user_id(),
54 58
55 59 ];
56 60
57 - if ( $endpoint !== self::STATUS_CHECK ) {
61 + if ( Optimize_Image::IMAGE_OPTIMIZE_ENDPOINT === $endpoint ) {
58 62 // Media library stats
59 63 $data['media_data'] = base64_encode( wp_json_encode( self::get_request_stats() ) ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
60 64 }
61 65
@@ -66,19 +70,35 @@
66 70 * Get site info
67 71 * @return mixed|WP_Error|null
68 72 */
69 73 public static function get_subscription_info() {
70 - $info = get_transient( self::SITE_INFO_TRANSIENT );
71 - if ( ! $info ) {
72 - try {
73 - $info = self::get_instance()->make_request( 'POST', self::SITE_INFO );
74 - } catch ( Throwable $t ) {
75 - Logger::log( Logger::LEVEL_ERROR, 'Cannot get site info response from service: ' . $t->getMessage() );
76 - return null;
77 - }
74 + $cached_info = get_transient( self::SITE_INFO_TRANSIENT );
78 75
79 - set_transient( self::SITE_INFO_TRANSIENT, $info, ( 24 * 60 * 60 ) );
76 + if ( $cached_info ) {
77 + return $cached_info;
80 78 }
79 +
80 + $cached_error = get_transient( self::SITE_INFO_TRANSIENT_ERROR );
81 +
82 + if ( $cached_error ) {
83 + Logger::debug( 'Status check skipped due to recent error: ' . $cached_error );
84 + return null;
85 + }
86 +
87 + try {
88 + $info = self::get_instance()->make_request( 'POST', self::SITE_INFO );
89 + } catch ( Throwable $t ) {
90 + $error_message = $t->getMessage();
91 +
92 + Logger::error( 'Cannot get site info response from service: ' . $error_message );
93 +
94 + set_transient( self::SITE_INFO_TRANSIENT_ERROR, $error_message, self::ERROR_CACHE_DURATION );
95 +
96 + return null;
97 + }
98 +
99 + set_transient( self::SITE_INFO_TRANSIENT, $info, DAY_IN_SECONDS );
100 +
81 101 return $info;
82 102 }
83 103
84 104 private static function get_request_stats(): array {
@@ -125,9 +145,9 @@
125 145 $response = $this->request(
126 146 $method,
127 147 $endpoint,
128 148 [
129 - 'timeout' => 100,
149 + 'timeout' => 50,
130 150 'headers' => $headers,
131 151 'body' => $body,
132 152 ]
133 153 );
@@ -134,11 +154,19 @@
134 154
135 155 return ( new Client_Response( $response ) )->handle();
136 156 }
137 157
158 + public static function get_feedback_base_url() {
159 + return apply_filters( 'image_optimizer_feedback_base_url', self::BASE_URL_FEEDBACK );
160 + }
161 +
138 162 private static function get_remote_url( $endpoint ): string {
139 163 $base_url = apply_filters( 'image_optimizer_client_get_base_url', self::BASE_URL );
140 164
165 + if ( strpos( $endpoint, 'feedback/' ) !== false ) {
166 + return self::get_feedback_base_url() . $endpoint;
167 + }
168 +
141 169 return $base_url . $endpoint;
142 170 }
143 171
144 172 protected function is_connected(): bool {
@@ -145,9 +173,8 @@
145 173 return Plugin::instance()->modules_manager->get_modules( 'connect-manager' )->connect_instance->is_connected();
146 174 }
147 175
148 176 protected function generate_authentication_headers( $endpoint ): array {
149 -
150 177 $connect_instance = Plugin::instance()->modules_manager->get_modules( 'connect-manager' )->connect_instance;
151 178
152 179 if ( ! $connect_instance->get_is_connect_on_fly() ) {
153 180 $headers = [
@@ -217,9 +244,15 @@
217 244 return $this->request( $method, $endpoint, $args );
218 245 }
219 246 }
220 247
221 - if ( 200 !== $response_code ) {
248 + // If there is mismatch then trigger the mismatch flow explicitly.
249 + if ( ! $this->refreshed && ! empty( $body->message ) && ( false !== strpos( $body->message, 'site url mismatch' ) ) ) {
250 + Connect_Module::get_connect()->data()->set_home_url( 'https://wrongurl' );
251 + return new WP_Error( 401, 'site url mismatch' );
252 + }
253 +
254 + if ( ! in_array( $response_code, [ 200, 201 ], true ) ) {
222 255 // In case $as_array = true.
223 256 $message = $body->message ?? wp_remote_retrieve_response_message( $response );
224 257 $message = is_array( $message ) ? join( ', ', $message ) : $message;
225 258 $code = isset( $body->code ) ? (int) $body->code : $response_code;
@@ -249,8 +282,9 @@
249 282 * @throws Client_Exception
250 283 */
251 284 private function get_upload_request_body( array $body, $file, string $boundary, string $file_name = '' ): string {
252 285 $payload = '';
286 +
253 287 // add all body fields as standard POST fields:
254 288 foreach ( $body as $name => $value ) {
255 289 $payload .= '--' . $boundary;
256 290 $payload .= "\r\n";
@@ -269,9 +303,9 @@
269 303 if (
270 304 ! in_array( $image_mime, Image::get_supported_mime_types(), true ) &&
271 305 ( 'application/octet-stream' === $image_mime && 'avif' !== File_Utils::get_extension( $file ) )
272 306 ) {
273 - throw new Client_Exception( "Unsupported mime type `$image_mime`" );
307 + throw new Client_Exception( esc_html( "Unsupported mime type `$image_mime`" ) );
274 308 }
275 309
276 310 if ( empty( $file_name ) ) {
277 311 $file_name = basename( $file );
@@ -294,15 +328,16 @@
294 328 * @return string
295 329 */
296 330 private function get_file_payload( string $filename, string $file_type, string $file_path, string $boundary ): string {
297 331 $name = $filename ?? basename( $file_path );
298 - $mine_type = 'image' === $file_type ? image_type_to_mime_type( exif_imagetype( $file_path ) ) : $file_type;
332 + $mime_type = 'image' === $file_type ? image_type_to_mime_type( exif_imagetype( $file_path ) ) : $file_type;
299 333 $payload = '';
334 +
300 335 // Upload the file
301 336 $payload .= '--' . $boundary;
302 337 $payload .= "\r\n";
303 338 $payload .= 'Content-Disposition: form-data; name="' . esc_attr( $name ) . '"; filename="' . esc_attr( $name ) . '"' . "\r\n";
304 - $payload .= 'Content-Type: ' . $mine_type . "\r\n";
339 + $payload .= 'Content-Type: ' . $mime_type . "\r\n";
305 340 $payload .= "\r\n";
306 341 $payload .= file_get_contents( $file_path );
307 342 $payload .= "\r\n";
308 343