| @@ -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 |
| @@ -7,8 +10,9 @@ | ||
| 7 | 10 | * @author Optimole <[email protected]> |
| 8 | 11 | */ |
| 9 | 12 | abstract class Optml_App_Replacer { |
| 10 | 13 | use Optml_Dam_Offload_Utils; |
| 14 | + | |
| 11 | 15 | /** |
| 12 | 16 | * Filters used for lazyload. |
| 13 | 17 | * |
| 14 | 18 | * @var array Lazyload filters. |
| @@ -56,8 +60,14 @@ | ||
| 56 | 60 | * @var Optml_Settings $settings |
| 57 | 61 | */ |
| 58 | 62 | public $settings = null; |
| 59 | 63 | /** |
| 64 | + * Cached offloading status. | |
| 65 | + * | |
| 66 | + * @var null|bool Offload status. | |
| 67 | + */ | |
| 68 | + public static $offload_enabled = null; | |
| 69 | + /** | |
| 60 | 70 | * Defines if the dimensions should be limited when images are served. |
| 61 | 71 | * |
| 62 | 72 | * @var bool |
| 63 | 73 | */ |
| @@ -172,9 +182,9 @@ | ||
| 172 | 182 | if ( null !== self::$ignore_lazyload_strings ) { |
| 173 | 183 | return self::$ignore_lazyload_strings; |
| 174 | 184 | } |
| 175 | 185 | |
| 176 | - 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' ] ); | |
| 177 | 187 | |
| 178 | 188 | return array_merge( self::$possible_src_attributes, [ '<noscript' ] ); |
| 179 | 189 | } |
| 180 | 190 | /** |
| @@ -188,9 +198,9 @@ | ||
| 188 | 198 | } |
| 189 | 199 | |
| 190 | 200 | self::$ignore_tag_strings = apply_filters( 'optml_skip_optimizations_css_classes', [ 'skip-optimization' ] ); |
| 191 | 201 | |
| 192 | - return self::$ignore_tag_strings; | |
| 202 | + return self::$ignore_tag_strings; | |
| 193 | 203 | } |
| 194 | 204 | /** |
| 195 | 205 | * Returns possible data-opt-src ignore flags attributes. |
| 196 | 206 | * |
| @@ -210,9 +220,9 @@ | ||
| 210 | 220 | * Size to crop maping. |
| 211 | 221 | * |
| 212 | 222 | * @return array Size mapping. |
| 213 | 223 | */ |
| 214 | - protected static function size_to_crop() { | |
| 224 | + public static function size_to_crop() { | |
| 215 | 225 | if ( ! empty( self::$size_to_crop ) ) { |
| 216 | 226 | return self::$size_to_crop; |
| 217 | 227 | } |
| 218 | 228 | |
| @@ -247,9 +257,8 @@ | ||
| 247 | 257 | 'height' => (int) $height, |
| 248 | 258 | 'enlarge' => true, |
| 249 | 259 | 'crop' => $crop, |
| 250 | 260 | ]; |
| 251 | - | |
| 252 | 261 | } |
| 253 | 262 | |
| 254 | 263 | /** |
| 255 | 264 | * Returns the array of image sizes since `get_intermediate_image_sizes` and image metadata doesn't include the |
| @@ -257,9 +266,9 @@ | ||
| 257 | 266 | * |
| 258 | 267 | * @return array |
| 259 | 268 | * @global $wp_additional_image_sizes |
| 260 | 269 | */ |
| 261 | - protected static function image_sizes() { | |
| 270 | + public static function image_sizes() { | |
| 262 | 271 | if ( ! empty( self::$image_sizes ) ) { |
| 263 | 272 | return self::$image_sizes; |
| 264 | 273 | } |
| 265 | 274 | |
| @@ -325,9 +334,9 @@ | ||
| 325 | 334 | |
| 326 | 335 | self::$filters = $this->settings->get_filters(); |
| 327 | 336 | add_filter( |
| 328 | 337 | 'optml_should_avif_ext', |
| 329 | - function( $should_avif, $ext ) { | |
| 338 | + function ( $should_avif, $ext ) { | |
| 330 | 339 | return $ext !== 'svg'; |
| 331 | 340 | }, |
| 332 | 341 | 10, |
| 333 | 342 | 2 |
| @@ -352,8 +361,11 @@ | ||
| 352 | 361 | return $strings; |
| 353 | 362 | }, |
| 354 | 363 | 10 |
| 355 | 364 | ); |
| 365 | + if ( self::$offload_enabled === null ) { | |
| 366 | + self::$offload_enabled = ( new Optml_Settings() )->is_offload_enabled(); | |
| 367 | + } | |
| 356 | 368 | } |
| 357 | 369 | |
| 358 | 370 | |
| 359 | 371 | /** |
| @@ -391,11 +403,12 @@ | ||
| 391 | 403 | $domain = $service_data['domain']; |
| 392 | 404 | } |
| 393 | 405 | Optml_Config::init( |
| 394 | 406 | [ |
| 395 | - 'key' => $service_data['cdn_key'], | |
| 396 | - 'secret' => $service_data['cdn_secret'], | |
| 397 | - 'domain' => $domain, | |
| 407 | + 'key' => $service_data['cdn_key'], | |
| 408 | + 'secret' => $service_data['cdn_secret'], | |
| 409 | + 'domain' => $domain, | |
| 410 | + 'api_key' => $this->settings->get( 'api_key' ), | |
| 398 | 411 | ] |
| 399 | 412 | ); |
| 400 | 413 | |
| 401 | 414 | if ( defined( 'OPTML_SITE_MIRROR' ) && constant( 'OPTML_SITE_MIRROR' ) ) { |
| @@ -467,9 +480,9 @@ | ||
| 467 | 480 | * @param mixed $crop Cropping behaviour. |
| 468 | 481 | * |
| 469 | 482 | * @return mixed Original value. |
| 470 | 483 | */ |
| 471 | - 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 ) { | |
| 472 | 485 | self::add_size( $dest_w, $dest_h, $crop ); |
| 473 | 486 | |
| 474 | 487 | return $value; |
| 475 | 488 | } |
| @@ -476,9 +489,9 @@ | ||
| 476 | 489 | |
| 477 | 490 | /** |
| 478 | 491 | * Extract domains and use them as keys for fast processing. |
| 479 | 492 | * |
| 480 | - * @param array $urls Input urls. | |
| 493 | + * @param array|null $urls Input urls. | |
| 481 | 494 | * |
| 482 | 495 | * @return array Array of domains as keys. |
| 483 | 496 | */ |
| 484 | 497 | protected function extract_domain_from_urls( $urls = [] ) { |
| @@ -515,9 +528,9 @@ | ||
| 515 | 528 | |
| 516 | 529 | /** |
| 517 | 530 | * Check if we can replace the url. |
| 518 | 531 | * |
| 519 | - * @param string $url Url to change. | |
| 532 | + * @param string|mixed $url Url to change. | |
| 520 | 533 | * |
| 521 | 534 | * @return bool Either we can replace this url or not. |
| 522 | 535 | */ |
| 523 | 536 | public function can_replace_url( $url ) { |
| @@ -562,13 +575,15 @@ | ||
| 562 | 575 | } |
| 563 | 576 | if ( preg_match( '#(-\d+x\d+(?:_c)?|(@2x))\.(' . implode( '|', array_keys( Optml_Config::$image_extensions ) ) . '){1}$#i', $url, $src_parts ) ) { |
| 564 | 577 | $stripped_url = str_replace( $src_parts[1], '', $url ); |
| 565 | 578 | |
| 566 | - // Treat offloaded attachments differently. | |
| 567 | - $id = $this->attachment_url_to_post_id( $stripped_url ); | |
| 579 | + if ( $this->settings->is_offload_enabled() ) { | |
| 580 | + // Treat offloaded attachments differently. | |
| 581 | + $id = $this->attachment_url_to_post_id( $stripped_url ); | |
| 568 | 582 | |
| 569 | - if ( $id !== 0 && $this->is_new_offloaded_attachment( $id ) ) { | |
| 570 | - return $stripped_url; | |
| 583 | + if ( $id !== 0 && $this->is_new_offloaded_attachment( $id ) ) { | |
| 584 | + return $stripped_url; | |
| 585 | + } | |
| 571 | 586 | } |
| 572 | 587 | |
| 573 | 588 | // Extracts the file path to the image minus the base url |
| 574 | 589 | $file_path = substr( $stripped_url, strpos( $stripped_url, $this->upload_resource['url'] ) + $this->upload_resource['url_length'] ); |
| @@ -596,8 +611,17 @@ | ||
| 596 | 611 | $crop = ( isset( $width_height_string[3] ) && $width_height_string[3] === '_c' ); |
| 597 | 612 | if ( $width && $height ) { |
| 598 | 613 | return [ $width, $height, $crop ]; |
| 599 | 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 | + } | |
| 600 | 624 | } |
| 601 | 625 | |
| 602 | 626 | return [ false, false, false ]; |
| 603 | 627 | } |
| @@ -612,11 +636,9 @@ | ||
| 612 | 636 | * @param array $resize Optml crop array. |
| 613 | 637 | * @return string The optimized url. |
| 614 | 638 | */ |
| 615 | 639 | public function get_media_optimized_url( $url, $table_id, $width = 'auto', $height = 'auto', $resize = [] ) { |
| 616 | - $optimized_url = ( new Optml_Image( $url, ['width' => $width, 'height' => $height, 'resize' => $resize, 'quality' => $this->settings->get_numeric_quality()], $this->settings->get( 'cache_buster' ) ) )->get_url(); | |
| 617 | - $optimized_url = str_replace( $url, Optml_Media_Offload::KEYS['not_processed_flag'] . 'media_cloud' . '/' . Optml_Media_Offload::KEYS['uploaded_flag'] . $table_id . '/' . $url, $optimized_url ); | |
| 618 | - return $optimized_url; | |
| 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 ) ); | |
| 619 | 641 | } |
| 620 | 642 | |
| 621 | 643 | /** |
| 622 | 644 | * Test that the url has the dam flag. |
| @@ -626,6 +648,51 @@ | ||
| 626 | 648 | * @return bool |
| 627 | 649 | */ |
| 628 | 650 | public function url_has_dam_flag( $url ) { |
| 629 | 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; | |
| 630 | 697 | } |
| 631 | 698 | } |