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/app_replacer.php +236 -80 2.5.5 → trunk View file →
@@ -1,6 +1,9 @@
1 1 <?php
2 2
3 +use Optimole\Sdk\Optimole;
4 +use Optimole\Sdk\ValueObject\Position;
5 +
3 6 /**
4 7 * Class Optml_App_Replacer
5 8 *
6 9 * @package \Optml\Inc
@@ -6,13 +9,14 @@
6 9 * @package \Optml\Inc
7 10 * @author Optimole <[email protected]>
8 11 */
9 12 abstract class Optml_App_Replacer {
13 + use Optml_Dam_Offload_Utils;
10 14
11 15 /**
12 16 * Filters used for lazyload.
13 17 *
14 - * @var null Lazyload filters.
18 + * @var array Lazyload filters.
15 19 */
16 20 protected static $filters = null;
17 21 /**
18 22 * Holds an array of image sizes.
@@ -18,15 +22,15 @@
18 22 * Holds an array of image sizes.
19 23 *
20 24 * @var array
21 25 */
22 - protected static $image_sizes = array();
26 + protected static $image_sizes = [];
23 27 /**
24 28 * Holds width/height to crop array based on possible image sizes.
25 29 *
26 30 * @var array
27 31 */
28 - protected static $size_to_crop = array();
32 + protected static $size_to_crop = [];
29 33 /**
30 34 * Holds possible src attributes.
31 35 *
32 36 * @var array
@@ -56,19 +60,31 @@
56 60 * @var Optml_Settings $settings
57 61 */
58 62 public $settings = null;
59 63 /**
60 - * Defines which is the maximum width accepted in the optimization process.
64 + * Cached offloading status.
61 65 *
66 + * @var null|bool Offload status.
67 + */
68 + public static $offload_enabled = null;
69 + /**
70 + * Defines if the dimensions should be limited when images are served.
71 + *
72 + * @var bool
73 + */
74 + protected $limit_dimensions_enabled = false;
75 + /**
76 + * Defines which is the maximum width accepted when images are served.
77 + *
62 78 * @var int
63 79 */
64 - protected $max_width = 3000;
80 + protected $limit_width = 1920;
65 81 /**
66 - * Defines which is the maximum width accepted in the optimization process.
82 + * Defines which is the maximum height accepted when images are served.
67 83 *
68 84 * @var int
69 85 */
70 - protected $max_height = 3000;
86 + protected $limit_height = 1080;
71 87 /**
72 88 * Defines if css minification should be used.
73 89 *
74 90 * @var int
@@ -82,9 +98,9 @@
82 98 protected $is_js_minify_on = 0;
83 99 /**
84 100 * A cached version of `wp_upload_dir`
85 101 *
86 - * @var null
102 + * @var null|array
87 103 */
88 104 protected $upload_resource = null;
89 105
90 106 /**
@@ -91,21 +107,21 @@
91 107 * Possible domain sources to optimize.
92 108 *
93 109 * @var array Domains.
94 110 */
95 - protected $possible_sources = array();
111 + protected $possible_sources = [];
96 112 /**
97 113 * Possible custom sizes definitions.
98 114 *
99 115 * @var array Custom sizes definitions.
100 116 */
101 - private static $custom_size_buffer = array();
117 + private static $custom_size_buffer = [];
102 118 /**
103 119 * Whitelisted domains sources to optimize from, according to optimole service.
104 120 *
105 121 * @var array Domains.
106 122 */
107 - protected $allowed_sources = array();
123 + protected $allowed_sources = [];
108 124
109 125 /**
110 126 * Holds site mapping array,
111 127 * if there is already a cdn and we want to fetch the images from there
@@ -112,20 +128,20 @@
112 128 * and not from he original site.
113 129 *
114 130 * @var array Site mappings.
115 131 */
116 - protected $site_mappings = array();
132 + protected $site_mappings = [];
117 133 /**
118 134 * Whether the site is whitelisted or not. Used when signing the urls.
119 135 *
120 136 * @var bool Domains.
121 137 */
122 - protected $is_allowed_site = array();
138 + protected $is_allowed_site = false;
123 139
124 140 /**
125 - * Holds the most recent value for the cache buster.
141 + * Holds the most recent value for the cache buster, updated to hold only for images if active_cache_buster_assets is defined.
126 142 *
127 - * @var string Cache Buster value.
143 + * @var string Cache Buster global value if active_cache_buster_assets is undefined else the value for images.
128 144 */
129 145 protected $active_cache_buster = '';
130 146
131 147 /**
@@ -132,18 +148,24 @@
132 148 * Holds possible ignored by class urls.
133 149 *
134 150 * @var array
135 151 */
136 - protected static $ignored_url_map = array();
152 + protected static $ignored_url_map = [];
137 153
138 154 /**
155 + * Holds the most recent value for the cache buster for assets.
156 + *
157 + * @var string Cache Buster value.
158 + */
159 + protected $active_cache_buster_assets = '';
160 +
161 + /**
139 162 * Returns possible src attributes.
140 163 *
141 164 * @return array
142 165 */
143 166 public static function possible_src_attributes() {
144 -
145 - if ( null != self::$possible_src_attributes && is_array( self::$possible_src_attributes ) ) {
167 + if ( null !== self::$possible_src_attributes ) {
146 168 return self::$possible_src_attributes;
147 169 }
148 170
149 171 self::$possible_src_attributes = apply_filters( 'optml_possible_src_attributes', [] );
@@ -156,14 +178,13 @@
156 178 *
157 179 * @return array
158 180 */
159 181 public static function possible_lazyload_flags() {
160 -
161 - if ( null != self::$ignore_lazyload_strings && is_array( self::$ignore_lazyload_strings ) ) {
182 + if ( null !== self::$ignore_lazyload_strings ) {
162 183 return self::$ignore_lazyload_strings;
163 184 }
164 185
165 - self::$possible_src_attributes = apply_filters( 'optml_possible_lazyload_flags', [ 'skip-lazy', 'data-skip-lazy' ] );
186 + self::$possible_src_attributes = apply_filters( 'optml_possible_lazyload_flags', [ 'skip-lazy', 'data-skip-lazy', 'data-opt-src' ] );
166 187
167 188 return array_merge( self::$possible_src_attributes, [ '<noscript' ] );
168 189 }
169 190 /**
@@ -171,16 +192,15 @@
171 192 *
172 193 * @return array
173 194 */
174 195 public static function possible_tag_flags() {
175 -
176 - if ( null != self::$ignore_tag_strings && is_array( self::$ignore_tag_strings ) ) {
196 + if ( null !== self::$ignore_tag_strings ) {
177 197 return self::$ignore_tag_strings;
178 198 }
179 199
180 200 self::$ignore_tag_strings = apply_filters( 'optml_skip_optimizations_css_classes', [ 'skip-optimization' ] );
181 201
182 - return self::$ignore_tag_strings;
202 + return self::$ignore_tag_strings;
183 203 }
184 204 /**
185 205 * Returns possible data-opt-src ignore flags attributes.
186 206 *
@@ -186,10 +206,9 @@
186 206 *
187 207 * @return array
188 208 */
189 209 public static function possible_data_ignore_flags() {
190 -
191 - if ( null != self::$ignore_data_opt_attribute && is_array( self::$ignore_data_opt_attribute ) ) {
210 + if ( null !== self::$ignore_data_opt_attribute ) {
192 211 return self::$ignore_data_opt_attribute;
193 212 }
194 213
195 214 self::$ignore_data_opt_attribute = apply_filters( 'optml_ignore_data_opt_flag', [] );
@@ -201,10 +220,10 @@
201 220 * Size to crop maping.
202 221 *
203 222 * @return array Size mapping.
204 223 */
205 - protected static function size_to_crop() {
206 - if ( null != self::$size_to_crop && is_array( self::$size_to_crop ) ) {
224 + public static function size_to_crop() {
225 + if ( ! empty( self::$size_to_crop ) ) {
207 226 return self::$size_to_crop;
208 227 }
209 228
210 229 foreach ( self::image_sizes() as $size_data ) {
@@ -223,16 +242,17 @@
223 242
224 243 /**
225 244 * Set possible custom size.
226 245 *
227 - * @param null $width Width value.
228 - * @param null $height Height Value.
229 - * @param null $crop Croping.
246 + * @param int $width Width value.
247 + * @param int $height Height Value.
248 + * @param bool|array $crop Croping.
230 249 */
231 250 public static function add_size( $width = null, $height = null, $crop = null ) {
232 - if ( empty( $width ) || empty( $height ) ) {
251 + if ( is_null( $width ) || is_null( $height ) ) {
233 252 return;
234 253 }
254 +
235 255 self::$custom_size_buffer[ 'cmole' . $width . $height ] = [
236 256 'width' => (int) $width,
237 257 'height' => (int) $height,
238 258 'enlarge' => true,
@@ -237,9 +257,8 @@
237 257 'height' => (int) $height,
238 258 'enlarge' => true,
239 259 'crop' => $crop,
240 260 ];
241 -
242 261 }
243 262
244 263 /**
245 264 * Returns the array of image sizes since `get_intermediate_image_sizes` and image metadata doesn't include the
@@ -247,11 +266,10 @@
247 266 *
248 267 * @return array
249 268 * @global $wp_additional_image_sizes
250 269 */
251 - protected static function image_sizes() {
252 -
253 - if ( null != self::$image_sizes && is_array( self::$image_sizes ) ) {
270 + public static function image_sizes() {
271 + if ( ! empty( self::$image_sizes ) ) {
254 272 return self::$image_sizes;
255 273 }
256 274
257 275 global $_wp_additional_image_sizes;
@@ -256,30 +274,30 @@
256 274
257 275 global $_wp_additional_image_sizes;
258 276
259 277 // Populate an array matching the data structure of $_wp_additional_image_sizes so we have a consistent structure for image sizes
260 - $images = array(
261 - 'thumb' => array(
278 + $images = [
279 + 'thumb' => [
262 280 'width' => intval( get_option( 'thumbnail_size_w' ) ),
263 281 'height' => intval( get_option( 'thumbnail_size_h' ) ),
264 282 'crop' => (bool) get_option( 'thumbnail_crop', false ),
265 - ),
266 - 'medium' => array(
283 + ],
284 + 'medium' => [
267 285 'width' => intval( get_option( 'medium_size_w' ) ),
268 286 'height' => intval( get_option( 'medium_size_h' ) ),
269 287 'crop' => false,
270 - ),
271 - 'large' => array(
288 + ],
289 + 'large' => [
272 290 'width' => intval( get_option( 'large_size_w' ) ),
273 291 'height' => intval( get_option( 'large_size_h' ) ),
274 292 'crop' => false,
275 - ),
276 - 'full' => array(
293 + ],
294 + 'full' => [
277 295 'width' => null,
278 296 'height' => null,
279 297 'crop' => false,
280 - ),
281 - );
298 + ],
299 + ];
282 300
283 301 // Compatibility mapping as found in wp-includes/media.php
284 302 $images['thumbnail'] = $images['thumb'];
285 303
@@ -303,9 +321,9 @@
303 321 },
304 322 self::$image_sizes
305 323 );
306 324
307 - return is_array( self::$image_sizes ) ? self::$image_sizes : array();
325 + return self::$image_sizes;
308 326 }
309 327
310 328 /**
311 329 * The initialize method.
@@ -315,10 +333,18 @@
315 333 $this->set_properties();
316 334
317 335 self::$filters = $this->settings->get_filters();
318 336 add_filter(
337 + 'optml_should_avif_ext',
338 + function ( $should_avif, $ext ) {
339 + return $ext !== 'svg';
340 + },
341 + 10,
342 + 2
343 + );
344 + add_filter(
319 345 'optml_possible_lazyload_flags',
320 - function ( $strings = array() ) {
346 + function ( $strings = [] ) {
321 347 foreach ( self::$filters[ Optml_Settings::FILTER_TYPE_LAZYLOAD ][ Optml_Settings::FILTER_CLASS ] as $rule_flag => $status ) {
322 348 $strings[] = $rule_flag;
323 349 }
324 350
@@ -323,22 +349,23 @@
323 349 }
324 350
325 351 return $strings;
326 352 },
327 - 10,
328 - 2
353 + 10
329 354 );
330 355 add_filter(
331 356 'optml_skip_optimizations_css_classes',
332 - function ( $strings = array() ) {
357 + function ( $strings = [] ) {
333 358 foreach ( self::$filters[ Optml_Settings::FILTER_TYPE_OPTIMIZE ][ Optml_Settings::FILTER_CLASS ] as $rule_flag => $status ) {
334 359 $strings[] = $rule_flag;
335 360 }
336 361 return $strings;
337 362 },
338 - 10,
339 - 2
363 + 10
340 364 );
365 + if ( self::$offload_enabled === null ) {
366 + self::$offload_enabled = ( new Optml_Settings() )->is_offload_enabled();
367 + }
341 368 }
342 369
343 370
344 371 /**
@@ -346,28 +373,43 @@
346 373 */
347 374 public function set_properties() {
348 375
349 376 $upload_data = wp_upload_dir();
350 - $this->upload_resource = array(
351 - 'url' => str_replace( array( 'https://', 'http://' ), '', $upload_data['baseurl'] ),
377 + $this->upload_resource = [
378 + 'url' => str_replace( [ 'https://', 'http://' ], '', $upload_data['baseurl'] ),
352 379 'directory' => $upload_data['basedir'],
353 - );
380 + ];
354 381 $this->upload_resource['url_length'] = strlen( $this->upload_resource['url'] );
355 382
356 - $content_parts = parse_url( content_url() );
383 + $content_url = content_url();
357 384
358 - $this->upload_resource['content_path'] = $content_parts['path'];
359 - $this->upload_resource['content_folder'] = ltrim( $content_parts['path'], '/' );
385 + if ( strpos( $content_url, '/' ) === 0 ) {
386 + $content_url = get_site_url() . $content_url;
387 + }
388 + $content_parts = parse_url( $content_url );
389 + $this->upload_resource['content_path'] = '/';
390 + $this->upload_resource['content_folder'] = '/';
391 + if ( isset( $content_parts['path'] ) ) {
392 + $this->upload_resource['content_path'] = $content_parts['path'];
393 + $this->upload_resource['content_folder'] = ltrim( $content_parts['path'], '/' );
394 + }
395 +
360 396 $this->upload_resource['content_folder_length'] = strlen( $this->upload_resource['content_folder'] );
361 397 $this->upload_resource['content_host'] = $content_parts['scheme'] . '://' . $content_parts['host'];
362 398
363 399 $service_data = $this->settings->get( 'service_data' );
364 400
401 + $domain = '';
402 + if ( isset( $service_data['is_cname_assigned'] ) && $service_data['is_cname_assigned'] === 'yes' && ! empty( $service_data['domain'] ) ) {
403 + $domain = $service_data['domain'];
404 + }
365 405 Optml_Config::init(
366 - array(
367 - 'key' => $service_data['cdn_key'],
368 - 'secret' => $service_data['cdn_secret'],
369 - )
406 + [
407 + 'key' => $service_data['cdn_key'],
408 + 'secret' => $service_data['cdn_secret'],
409 + 'domain' => $domain,
410 + 'api_key' => $this->settings->get( 'api_key' ),
411 + ]
370 412 );
371 413
372 414 if ( defined( 'OPTML_SITE_MIRROR' ) && constant( 'OPTML_SITE_MIRROR' ) ) {
373 415 $this->site_mappings[ rtrim( get_home_url(), '/' ) ] = rtrim( constant( 'OPTML_SITE_MIRROR' ), '/' );
@@ -374,9 +416,11 @@
374 416 }
375 417
376 418 $this->possible_sources = $this->extract_domain_from_urls(
377 419 array_merge(
378 - array( get_home_url() ),
420 + [
421 + get_home_url(),
422 + ],
379 423 array_values( $this->site_mappings ),
380 424 array_keys( $this->site_mappings )
381 425 )
382 426 );
@@ -381,9 +425,18 @@
381 425 )
382 426 );
383 427
384 428 $this->allowed_sources = $this->extract_domain_from_urls( $service_data['whitelist'] );
385 - $this->active_cache_buster = $this->settings->get( 'cache_buster' );
429 + $this->active_cache_buster = $this->settings->get( 'cache_buster_images' );
430 + $this->active_cache_buster_assets = $this->settings->get( 'cache_buster_assets' );
431 +
432 + if ( empty( $this->active_cache_buster ) ) {
433 + $this->active_cache_buster = $this->settings->get( 'cache_buster' );
434 + }
435 + if ( empty( $this->active_cache_buster_assets ) ) {
436 + $this->active_cache_buster_assets = $this->settings->get( 'cache_buster' );
437 + }
438 +
386 439 // Allways allow Photon urls.
387 440 $this->allowed_sources['i0.wp.com'] = true;
388 441 $this->allowed_sources['i1.wp.com'] = true;
389 442 $this->allowed_sources['i2.wp.com'] = true;
@@ -388,15 +441,18 @@
388 441 $this->allowed_sources['i1.wp.com'] = true;
389 442 $this->allowed_sources['i2.wp.com'] = true;
390 443 $this->is_allowed_site = count( array_diff_key( $this->possible_sources, $this->allowed_sources ) ) > 0;
391 444
392 - $this->max_height = $this->settings->get( 'max_height' );
393 - $this->max_width = $this->settings->get( 'max_width' );
445 + $this->limit_dimensions_enabled = $this->settings->get( 'limit_dimensions' ) === 'enabled';
446 + if ( $this->limit_dimensions_enabled ) {
447 + $this->limit_height = $this->settings->get( 'limit_height' );
448 + $this->limit_width = $this->settings->get( 'limit_width' );
449 + }
394 450
395 451 $this->is_css_minify_on = ( $this->settings->get( 'css_minify' ) === 'enabled' ) ? 1 : 0;
396 452 $this->is_js_minify_on = ( $this->settings->get( 'js_minify' ) === 'enabled' ) ? 1 : 0;
397 453
398 - add_filter( 'optml_strip_image_size_from_url', [ $this, 'strip_image_size_from_url' ], 10, 1 );
454 + add_filter( 'optml_strip_image_size_from_url', [ $this, 'strip_image_size_from_url' ], 10 );
399 455 add_filter(
400 456 'image_resize_dimensions',
401 457 [ __CLASS__, 'listen_to_sizes' ],
402 458 999999,
@@ -406,9 +462,9 @@
406 462
407 463 /**
408 464 * Method to expose upload resource property.
409 465 *
410 - * @return null
466 + * @return null|array
411 467 */
412 468 public function get_upload_resource() {
413 469 return $this->upload_resource;
414 470 }
@@ -424,9 +480,9 @@
424 480 * @param mixed $crop Cropping behaviour.
425 481 *
426 482 * @return mixed Original value.
427 483 */
428 - static function listen_to_sizes( $value, $orig_w, $orig_h, $dest_w, $dest_h, $crop ) {
484 + public static function listen_to_sizes( $value, $orig_w, $orig_h, $dest_w, $dest_h, $crop ) {
429 485 self::add_size( $dest_w, $dest_h, $crop );
430 486
431 487 return $value;
432 488 }
@@ -433,13 +489,13 @@
433 489
434 490 /**
435 491 * Extract domains and use them as keys for fast processing.
436 492 *
437 - * @param array $urls Input urls.
493 + * @param array|null $urls Input urls.
438 494 *
439 495 * @return array Array of domains as keys.
440 496 */
441 - protected function extract_domain_from_urls( $urls = array() ) {
497 + protected function extract_domain_from_urls( $urls = [] ) {
442 498 if ( ! is_array( $urls ) ) {
443 499 return [];
444 500 }
445 501
@@ -445,10 +501,15 @@
445 501
446 502 $urls = array_map(
447 503 function ( $value ) {
448 504 $parts = parse_url( $value );
449 -
450 - return isset( $parts['host'] ) ? $parts['host'] : '';
505 + $domain = '';
506 + if ( isset( $parts['host'] ) ) {
507 + $domain = $parts['host'];
508 + } elseif ( isset( $parts['path'] ) ) {
509 + $domain = $parts['path'];
510 + }
511 + return $domain;
451 512 },
452 513 $urls
453 514 );
454 515 $urls = array_filter( $urls );
@@ -467,9 +528,9 @@
467 528
468 529 /**
469 530 * Check if we can replace the url.
470 531 *
471 - * @param string $url Url to change.
532 + * @param string|mixed $url Url to change.
472 533 *
473 534 * @return bool Either we can replace this url or not.
474 535 */
475 536 public function can_replace_url( $url ) {
@@ -477,8 +538,12 @@
477 538 if ( ! is_string( $url ) ) {
478 539 return false; // @codeCoverageIgnore
479 540 }
480 541
542 + if ( $this->url_has_dam_flag( $url ) ) {
543 + return true;
544 + }
545 +
481 546 $url_parts = parse_url( $url );
482 547
483 548 if ( ! isset( $url_parts['host'] ) ) {
484 549 return false;
@@ -504,15 +569,27 @@
504 569 *
505 570 * @return string
506 571 **/
507 572 public function strip_image_size_from_url( $url ) {
508 -
573 + if ( apply_filters( 'optml_should_skip_strip_image_size', false, $url ) === true ) {
574 + return $url;
575 + }
509 576 if ( preg_match( '#(-\d+x\d+(?:_c)?|(@2x))\.(' . implode( '|', array_keys( Optml_Config::$image_extensions ) ) . '){1}$#i', $url, $src_parts ) ) {
510 577 $stripped_url = str_replace( $src_parts[1], '', $url );
578 +
579 + if ( $this->settings->is_offload_enabled() ) {
580 + // Treat offloaded attachments differently.
581 + $id = $this->attachment_url_to_post_id( $stripped_url );
582 +
583 + if ( $id !== 0 && $this->is_new_offloaded_attachment( $id ) ) {
584 + return $stripped_url;
585 + }
586 + }
587 +
511 588 // Extracts the file path to the image minus the base url
512 589 $file_path = substr( $stripped_url, strpos( $stripped_url, $this->upload_resource['url'] ) + $this->upload_resource['url_length'] );
513 590 if ( file_exists( $this->upload_resource['directory'] . $file_path ) ) {
514 - $url = $stripped_url;
591 + return $stripped_url;
515 592 }
516 593 }
517 594
518 595 return $url;
@@ -525,9 +602,9 @@
525 602 *
526 603 * @return array An array consisting of width and height.
527 604 */
528 605 protected function parse_dimensions_from_filename( $src ) {
529 - $width_height_string = array();
606 + $width_height_string = [];
530 607 $extensions = array_keys( Optml_Config::$image_extensions );
531 608 if ( preg_match( '#-(\d+)x(\d+)(:?_c)?\.(?:' . implode( '|', $extensions ) . '){1}$#i', $src, $width_height_string ) ) {
532 609 $width = (int) $width_height_string[1];
533 610 $height = (int) $width_height_string[2];
@@ -532,11 +609,90 @@
532 609 $width = (int) $width_height_string[1];
533 610 $height = (int) $width_height_string[2];
534 611 $crop = ( isset( $width_height_string[3] ) && $width_height_string[3] === '_c' );
535 612 if ( $width && $height ) {
536 - return array( $width, $height, $crop );
613 + return [ $width, $height, $crop ];
537 614 }
615 + } else {
616 + $optimized_args = $this->parse_dimension_from_optimized_url( $src );
617 + if ( $optimized_args[0] !== false || $optimized_args[1] !== false ) {
618 + return [
619 + $optimized_args[0] !== 'auto' ? (int) $optimized_args[0] : false,
620 + $optimized_args[1] !== 'auto' ? (int) $optimized_args[1] : false,
621 + false,
622 + ];
623 + }
538 624 }
539 625
540 - return array( false, false, false );
626 + return [ false, false, false ];
627 + }
628 +
629 + /**
630 + * Get the optimized urls for the wp media modal.
631 + *
632 + * @param string $url Original url.
633 + * @param string $table_id The cloud id of the image.
634 + * @param int|string $width Image width.
635 + * @param int|string $height Image height.
636 + * @param array $resize Optml crop array.
637 + * @return string The optimized url.
638 + */
639 + public function get_media_optimized_url( $url, $table_id, $width = 'auto', $height = 'auto', $resize = [] ) {
640 + return str_replace( $url, Optml_Media_Offload::KEYS['not_processed_flag'] . 'media_cloud' . '/' . Optml_Media_Offload::KEYS['uploaded_flag'] . $table_id . '/' . $url, $this->get_optimized_image_url( $url, $width, $height, $resize ) );
641 + }
642 +
643 + /**
644 + * Test that the url has the dam flag.
645 + *
646 + * @param string $url The image URL to check.
647 + *
648 + * @return bool
649 + */
650 + public function url_has_dam_flag( $url ) {
651 + return strpos( $url, Optml_Dam::URL_DAM_FLAG ) !== false;
652 + }
653 +
654 + /**
655 + * Get the optimized image url for the image url.
656 + *
657 + * @param string $url The image URL.
658 + * @param mixed $width The image width.
659 + * @param mixed $height The image height.
660 + * @param array<string, mixed>|mixed $resize The resize properties.
661 + *
662 + * @return string
663 + */
664 + protected function get_optimized_image_url( $url, $width, $height, $resize = [] ) {
665 + $width = is_int( $width ) ? $width : 'auto';
666 + $height = is_int( $height ) ? $height : 'auto';
667 + // If the image is already using Optimole URL, we extract the source to rebuild it.
668 + $url = $this->get_unoptimized_url( $url );
669 +
670 + $optimized_image = Optimole::image( $url, $this->settings->get( 'cache_buster' ) )
671 + ->width( $width )
672 + ->height( $height );
673 +
674 + if ( is_array( $resize ) && ! empty( $resize['type'] ) ) {
675 + $optimized_image->resize( $resize['type'], $resize['gravity'] ?? Position::CENTER, $resize['enlarge'] ?? false );
676 +
677 + }
678 +
679 + $optimized_image->quality( $this->settings->to_accepted_quality( $this->settings->get_quality() ) );
680 +
681 + return $optimized_image->getUrl();
682 + }
683 +
684 + /**
685 + * Returns an image id from the url.
686 + *
687 + * @param string $url The image URL.
688 + *
689 + * @return int
690 + */
691 + public function get_id_by_url( $url ) {
692 + $url = $this->get_unoptimized_url( $url );
693 + srand( crc32( $url ) );
694 + $random_id = rand();
695 + srand();
696 + return $random_id;
541 697 }
542 698 }