PluginProbe
Optimole – Optimize Images | Convert WebP & AVIF | CDN & Lazy Load | Image Optimization / trunk
Optimole – Optimize Images | Convert WebP & AVIF | CDN & Lazy Load | Image Optimization vtrunk
4.2.14 4.2.13 4.2.12 4.2.11 4.2.10 4.2.9 4.2.8 4.2.7 4.2.6 4.2.5 2.5.5 2.5.6 2.5.7 3.0.0 3.0.1 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.11.0 3.11.1 3.11.2 3.11.3 3.12.0 All 135 releases
← All changes | inc/api.php +87 -135 3.10.0 → trunk View file →
@@ -15,14 +15,8 @@
15 15 * @var string Api root.
16 16 */
17 17 private $api_root = 'https://dashboard.optimole.com/api/';
18 18 /**
19 - * Optimole upload api root url.
20 - *
21 - * @var string Api root.
22 - */
23 - private $upload_api_root = 'https://generateurls-prod.i.optimole.com/upload';
24 - /**
25 19 * Optimole onboard api root url.
26 20 *
27 21 * @var string Api root.
28 22 */
@@ -44,18 +38,15 @@
44 38 */
45 39 public function __construct() {
46 40 $settings = new Optml_Settings();
47 41 $this->api_key = $settings->get( 'api_key' );
48 - if ( defined( 'OPTIML_API_ROOT' ) && constant( 'OPTIML_API_ROOT' ) ) {
42 + if ( defined( 'OPTIML_API_ROOT' ) ) {
49 43 $this->api_root = constant( 'OPTIML_API_ROOT' );
50 44 }
51 - if ( defined( 'OPTIML_UPLOAD_API_ROOT' ) && constant( 'OPTIML_UPLOAD_API_ROOT' ) ) {
52 - $this->upload_api_root = constant( 'OPTIML_UPLOAD_API_ROOT' );
53 - }
54 - if ( defined( 'OPTIML_ONBOARD_API_ROOT' ) && constant( 'OPTIML_ONBOARD_API_ROOT' ) ) {
45 + if ( defined( 'OPTIML_ONBOARD_API_ROOT' ) ) {
55 46 $this->onboard_api_root = constant( 'OPTIML_ONBOARD_API_ROOT' );
56 47 }
57 - if ( defined( 'OPTIML_UPLOAD_CONFLICTS_API_ROOT' ) && constant( 'OPTIML_UPLOAD_CONFLICTS_API_ROOT' ) ) {
48 + if ( defined( 'OPTIML_UPLOAD_CONFLICTS_API_ROOT' ) ) {
58 49 $this->upload_conflicts_api = constant( 'OPTIML_UPLOAD_CONFLICTS_API_ROOT' );
59 50 }
60 51 }
61 52
@@ -70,12 +61,36 @@
70 61 if ( ! empty( $api_key ) ) {
71 62 $this->api_key = $api_key;
72 63 }
73 64
74 - return $this->request( '/optml/v2/account/connect', 'POST' );
65 + return $this->request( '/optml/v2/account/connect', 'POST', [ 'sample_image' => $this->get_sample_image() ] );
75 66 }
76 67
77 68 /**
69 + * Get sample image.
70 + *
71 + * @return string
72 + */
73 + private function get_sample_image() {
74 + $accepted_mimes = [ 'image/jpeg', 'image/png', 'image/webp' ];
75 + $args = [
76 + 'post_type' => 'attachment',
77 + 'post_status' => 'any',
78 + 'number' => '1',
79 + 'no_found_rows' => true,
80 + 'fields' => 'ids',
81 + 'post_mime_type' => $accepted_mimes,
82 + 'post_parent__not_in' => [ 0 ],
83 + ];
84 + $image_result = new WP_Query( $args );
85 + $original_image_url = 'none';
86 + if ( ! empty( $image_result->posts ) ) {
87 + $original_image_url = wp_get_attachment_image_url( $image_result->posts[0], 'full' );
88 + }
89 +
90 + return $original_image_url;
91 + }
92 + /**
78 93 * Get user data from service.
79 94 *
80 95 * @return array|string|bool|WP_Error User data.
81 96 */
@@ -111,11 +126,15 @@
111 126 public function get_cache_token( $token = '', $type = '', $api_key = '' ) {
112 127 if ( ! empty( $api_key ) ) {
113 128 $this->api_key = $api_key;
114 129 }
115 - $lock = get_transient( 'optml_cache_lock' );
116 - if ( ! empty( $type ) && $type === 'assets' ) {
130 + $lock = '';
131 + if ( empty( $type ) || $type === 'images' ) {
132 + $lock = get_transient( 'optml_cache_lock' );
133 + } elseif ( $type === 'assets' ) {
117 134 $lock = get_transient( 'optml_cache_lock_assets' );
135 + } else {
136 + $type = 'images';
118 137 }
119 138
120 139 if ( $lock === 'yes' ) {
121 140 return new WP_Error( 'cache_throttle', __( 'You can clear cache only once per 5 minutes.', 'optimole-wp' ) );
@@ -131,19 +150,18 @@
131 150 * @param array|string $params The request method type.
132 151 *
133 152 * @return array|string|boolean|WP_Error Api data.
134 153 */
135 - private function request( $path, $method = 'GET', $params = [], $extra_headers = [] ) {
154 + public function request( $path, $method = 'GET', $params = [], $extra_headers = [] ) {
136 155
137 156 $headers = [
138 157 'Optml-Site' => get_home_url(),
139 158 ];
159 + update_option( 'optimole_wp_logger_flag', 'yes' );
140 160 if ( ! empty( $this->api_key ) ) {
141 161 $headers['Authorization'] = 'Bearer ' . $this->api_key;
142 162 }
143 - if ( is_array( $headers ) ) {
144 - $headers = array_merge( $headers, $extra_headers );
145 - }
163 + $headers = array_merge( $headers, $extra_headers );
146 164 $url = trailingslashit( $this->api_root ) . ltrim( $path, '/' );
147 165 // If there is a extra, add that as a url var.
148 166 if ( 'GET' === $method && ! empty( $params ) ) {
149 167 foreach ( $params as $key => $val ) {
@@ -149,18 +167,18 @@
149 167 foreach ( $params as $key => $val ) {
150 168 $url = add_query_arg( [ $key => $val ], $url );
151 169 }
152 170 }
171 + $url = tsdk_translate_link( $url, 'query' );
172 +
153 173 $args = $this->build_args( $method, $url, $headers, $params );
154 174
155 175 $response = wp_remote_request( $url, $args );
156 -
157 176 if ( is_wp_error( $response ) ) {
158 177 return $response;
159 178 }
160 179
161 180 $response = wp_remote_retrieve_body( $response );
162 -
163 181 if ( empty( $response ) ) {
164 182 return false;
165 183 }
166 184 $response = json_decode( $response, true );
@@ -172,8 +190,11 @@
172 190 return false;
173 191 }
174 192
175 193 if ( intval( $response['code'] ) !== 200 ) {
194 + if ( isset( $response['error'] ) && $response['error'] === 'domain_not_accessible' ) {
195 + return new WP_Error( 'domain_not_accessible', sprintf( /* translators: 1 start of the italic tag, 2 is the end of italic tag, 3 is starting anchor tag, 4 is the ending anchor tag. */ __( 'It seems Optimole is having trouble reaching your website. This issue often occurs if your website is private, local, or protected by a firewall. But don\'t stress – it\'s an easy fix! Ensure your website is live and accessible to the public. If a firewall is in place, just tweak the settings to allow the %1$sOptimole(1.0)%2$s user agent access to your website. %3$sLearn More%4$s', 'optimole-wp' ), '<i>', '</i>', '<a href="https://docs.optimole.com/article/1976-resolving-optimole-access-to-your-website" target="_blank">', '</a>' ) );
196 + }
176 197 if ( $path === 'optml/v2/account/complete_register_remote' && isset( $response['error'] ) ) {
177 198 if ( strpos( $response['error'], 'This email address is already registered.' ) !== false ) {
178 199 return 'email_registered';
179 200 }
@@ -186,13 +207,29 @@
186 207 if ( $path === '/optml/v2/account/details'
187 208 && isset( $response['code'] ) && $response['code'] === 'not_allowed' ) {
188 209 return 'disconnect';
189 210 }
190 - return false;
211 +
212 + if ( $path === '/optml/v2/account/details'
213 + && isset( $response['error'] ) && $response['error'] === 'whitelist_limit_reached' ) {
214 + return 'disconnect';
215 + }
216 +
217 + return isset( $response['error'] ) ? new WP_Error(
218 + 'api_error',
219 + wp_kses(
220 + $response['error'],
221 + [
222 + 'a' => [
223 + 'href' => [],
224 + 'target' => [],
225 + ],
226 + ]
227 + )
228 + ) : false;
191 229 }
192 230
193 231 return $response['data'];
194 -
195 232 }
196 233
197 234 /**
198 235 * Builds Request arguments array.
@@ -219,21 +256,8 @@
219 256 return $args;
220 257 }
221 258
222 259 /**
223 - * Upload image to our servers using the generated signed url.
224 - *
225 - * @param string $upload_url The signed to url to upload the image to.
226 - * @param string $content_type Image mime type, it must match the actual mime type of the image.
227 - * @param string $image Image data from file_get_contents.
228 - * @return mixed
229 - */
230 - public function upload_image( $upload_url, $content_type, $image ) {
231 - $args = $this->build_args( 'PUT', '', ['content-type' => $content_type], $image );
232 - return wp_remote_request( $upload_url, $args );
233 - }
234 -
235 - /**
236 260 * Check if the optimized url is available.
237 261 *
238 262 * @param string $url The optimized url to check.
239 263 * @return bool Whether or not the url is valid.
@@ -238,9 +262,9 @@
238 262 * @param string $url The optimized url to check.
239 263 * @return bool Whether or not the url is valid.
240 264 */
241 265 public function check_optimized_url( $url ) {
242 - $response = wp_remote_get( $url, ['timeout' => 30] );
266 + $response = wp_remote_get( $url, [ 'timeout' => 30 ] );
243 267
244 268 if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 || ! empty( wp_remote_retrieve_header( $response, 'x-not-found-o' ) ) ) {
245 269 $this->log_offload_error( $response );
246 270 return false;
@@ -248,49 +272,8 @@
248 272 return true;
249 273 }
250 274
251 275 /**
252 - * Get options for the signed urls api call.
253 - *
254 - * @param string $original_url Image original url.
255 - * @param string $delete Whether to delete a bucket object or not(ie. generate signed upload url).
256 - * @param string $table_id Remote id used on our servers.
257 - * @param string $update_table False or success.
258 - * @param string $get_url Whether to return a get url or not.
259 - * @param string $width Original image width.
260 - * @param string $height Original image height.
261 - * @param int $file_size Original file size.
262 - * @return array|WP_Error
263 - */
264 - public function call_upload_api( $original_url = '', $delete = 'false', $table_id = '', $update_table = 'false', $get_url = 'false', $width = 'auto', $height = 'auto', $file_size = 0 ) {
265 - $body = [
266 - 'secret' => Optml_Config::$secret,
267 - 'userKey' => Optml_Config::$key,
268 - 'originalUrl' => $original_url,
269 - 'deleteUrl' => $delete,
270 - 'id' => $table_id,
271 - 'updateDynamo' => $update_table,
272 - 'getUrl' => $get_url,
273 - 'width' => $width,
274 - 'height' => $height,
275 - 'originalFileSize' => $file_size,
276 - ];
277 - $body = wp_json_encode( $body );
278 -
279 - $options = [
280 - 'body' => $body,
281 - 'headers' => [
282 - 'Content-Type' => 'application/json',
283 - ],
284 - 'timeout' => 60,
285 - 'blocking' => true,
286 - 'sslverify' => false,
287 - 'data_format' => 'body',
288 - ];
289 - return wp_remote_post( $this->upload_api_root, $options );
290 - }
291 -
292 - /**
293 276 * Send a list of images to upload.
294 277 *
295 278 * @param array $images List of Images.
296 279 * @return array
@@ -327,9 +310,9 @@
327 310 * @param array $images List of images.
328 311 * @return array
329 312 */
330 313 public function call_data_enrich_api( $images = [] ) {
331 - return $this->request( 'optml/v2/media/add_data', 'POST', ['images' => $images, 'key' => Optml_Config::$key] );
314 + return $this->request( 'optml/v2/media/add_data', 'POST', [ 'images' => $images, 'key' => Optml_Config::$key ] );
332 315 }
333 316 /**
334 317 * Register user remotely on optimole.com.
335 318 *
@@ -343,9 +326,11 @@
343 326 'POST',
344 327 [
345 328 'email' => $email,
346 329 'version' => OPTML_VERSION,
330 + 'sample_image' => $this->get_sample_image(),
347 331 'site' => get_home_url(),
332 + 'reference' => get_option( 'optimole_reference_key', '' ),
348 333 ]
349 334 );
350 335 }
351 336
@@ -365,65 +350,12 @@
365 350 $service_data = $settings->get( 'service_data' );
366 351 if ( isset( $service_data['cdn_key'] ) ) {
367 352 $app_key = $service_data['cdn_key'];
368 353 }
369 - return $this->request( '/optml/v1/stats/images', 'GET', [], ['application' => $app_key] );
354 + return $this->request( '/optml/v1/stats/images', 'GET', [], [ 'application' => $app_key ] );
370 355 }
371 356
372 357 /**
373 - * Get the watermarks from API.
374 - *
375 - * @param string $api_key The API key.
376 - *
377 - * @return array|bool|WP_Error
378 - */
379 - public function get_watermarks( $api_key = '' ) {
380 - if ( ! empty( $api_key ) ) {
381 - $this->api_key = $api_key;
382 - }
383 -
384 - return $this->request( '/optml/v1/settings/watermark' );
385 - }
386 -
387 - /**
388 - * Remove the watermark from the API.
389 - *
390 - * @param integer $post_id The watermark post ID.
391 - * @param string $api_key The API key.
392 - *
393 - * @return array|bool|WP_Error
394 - */
395 - public function remove_watermark( $post_id, $api_key = '' ) {
396 - if ( ! empty( $api_key ) ) {
397 - $this->api_key = $api_key;
398 - }
399 -
400 - return $this->request( '/optml/v1/settings/watermark', 'DELETE', [ 'watermark' => $post_id ] );
401 - }
402 -
403 - /**
404 - * Add watermark.
405 - *
406 - * @param array $file The file to be uploaded.
407 - *
408 - * @return array|bool|mixed|object
409 - */
410 - public function add_watermark( $file ) {
411 -
412 - $headers = [
413 - 'Content-Disposition' => 'attachment; filename=' . $file['file']['name'],
414 - ];
415 -
416 - $response = $this->request( 'wp/v2/media', 'POST', file_get_contents( $file['file']['tmp_name'] ), $headers );
417 -
418 - if ( $response === false ) {
419 - return false;
420 - }
421 -
422 - return $response;
423 - }
424 -
425 - /**
426 358 * Call the images endpoint.
427 359 *
428 360 * @param integer $page Page used to advance the search.
429 361 * @param array $domains Domains to filter by.
@@ -431,9 +363,9 @@
431 363 * @return mixed The decoded json response from the api.
432 364 */
433 365 public function get_cloud_images( $page = 0, $domains = [], $search = '' ) {
434 366
435 - $params = ['key' => Optml_Config::$key ];
367 + $params = [ 'key' => Optml_Config::$key ];
436 368 $params['page'] = $page;
437 369 $params['size'] = 40;
438 370 if ( $search !== '' ) {
439 371 $params['search'] = $search;
@@ -469,9 +401,9 @@
469 401 }
470 402 wp_remote_post(
471 403 $this->upload_conflicts_api,
472 404 [
473 - 'headers' => [ 'Content-Type' => 'application/json' ],
405 + 'headers' => [ 'Content-Type' => 'application/json' ],
474 406 'timeout' => 15,
475 407 'blocking' => true,
476 408 'sslverify' => false,
477 409 'data_format' => 'body',
@@ -479,8 +411,28 @@
479 411 'error_body' => wp_json_encode( $body ),
480 412 'error_headers' => $headers_to_log,
481 413 'error_site' => wp_json_encode( get_home_url() ),
482 414 ],
415 + ]
416 + );
417 + }
418 +
419 + /**
420 + * Send Offloading Logs
421 + *
422 + * @param string $type Type of log (offload/rollback).
423 + * @param string $message Log message.
424 + *
425 + * @return mixed
426 + */
427 + public function send_log( $type, $message ) {
428 + return $this->request(
429 + 'optml/v2/logs',
430 + 'POST',
431 + [
432 + 'type' => $type,
433 + 'message' => $message,
434 + 'site' => get_home_url(),
483 435 ]
484 436 );
485 437 }
486 438