uawdijnntqw1x1x1
IP : 216.73.216.109
Hostname : premium160.web-hosting.com
Kernel : Linux premium160.web-hosting.com 4.18.0-553.54.1.lve.el8.x86_64 #1 SMP Wed Jun 4 13:01:13 UTC 2025 x86_64
Disable Function : None :)
OS : Linux
PATH:
/
home
/
batcwwjx
/
.
/
public_html
/
wp-content
/
plugins
/
wp-smushit
/
core
/
cdn
/
class-cdn-srcset-controller.php
/
/
<?php /** * CDN class: CDN * * @package Smush\Core\Modules * @version 3.0 */ namespace Smush\Core\CDN; use Smush\Core\Controller; use Smush\Core\Media\Media_Item_Cache; use Smush\Core\Modules\Helpers; use Smush\Core\Settings; use Smush\Core\Srcset\Srcset_Helper; use Smush\Core\Url_Utils; use stdClass; use WP_Error; if ( ! defined( 'WPINC' ) ) { die; } /** * Class CDN * TODO: cleanup everything that has been moved to the transform class */ class CDN_Srcset_Controller extends Controller { /** * Module slug. * * @var string */ protected $slug = 'cdn'; /** * Whether module is pro or not. * * @var string */ protected $is_pro = true; /** * Supported file extensions. * * @var array $supported_extensions */ private $supported_extensions = array( 'gif', 'jpg', 'jpeg', 'png', 'webp', ); /** * @var CDN_Helper */ private $cdn_helper; /** * @var Settings|null */ private $settings; /** * Static instance * * @var self */ private static $instance; /** * @var Url_Utils */ private $urls_utils; /** * @var Srcset_Helper */ private $srcset_helper; /** * @var Media_Item_Cache */ private $media_item_cache; /** * Static instance getter */ public static function get_instance() { if ( empty( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } /** * CDN constructor. * * @since 3.2.2 */ public function __construct() { $this->settings = Settings::get_instance(); $this->cdn_helper = CDN_Helper::get_instance(); $this->urls_utils = new Url_Utils(); $this->srcset_helper = Srcset_Helper::get_instance(); $this->media_item_cache = Media_Item_Cache::get_instance(); $this->register_filter( 'wp_calculate_image_srcset', array( $this, 'update_image_srcset_in_ajax' ), $this->get_cdn_srcset_priority(), 5 ); } public function should_run() { return ! is_admin() && $this->cdn_helper->is_cdn_active(); } /************************************** * * PUBLIC METHODS CDN * * @see parse_image() * @see parse_background_image() * @see process_src() * @see update_image_srcset() * @see update_image_sizes() * @see update_cdn_image_src_args() * @see process_cdn_status() */ /** * Parse image for CDN. * * @param string $src Image URL. * @param string $image Image tag (<img>). * @param string $srcset Image srcset content. * @param string $type Element type. Accepts: 'img', 'source' or 'iframe'. Default: 'img'. * * @return string * @since 3.5.0 Added $srcset and $type params. * * @since 3.2.2 Moved out to a separate function. */ public function parse_image( $src, $image, $srcset = '', $type = 'img' ) { /** * Filter to skip a single image from cdn. * * @param bool $skip Should skip? Default: false. * @param string $src Image url. * @param array|bool $image Image tag or false. */ if ( apply_filters( 'smush_skip_image_from_cdn', false, $src, $image ) ) { return $image; } $new_image = $image; /** * Support for source in picture element. */ if ( 'source' === $type && $srcset ) { $links = Helpers\Parser::get_links_from_content( $srcset ); if ( ! isset( $links[0] ) || ! is_array( $links[0] ) ) { return $new_image; } foreach ( $links[0] as $link ) { if ( ! $this->cdn_helper->is_supported_url( $link ) ) { continue; } // Replace the data-envira-srcset of the image with CDN link. $src = $link; $src = $this->cdn_helper->generate_cdn_url( $src ); if ( $src ) { // Replace the src of the image with CDN link. $new_image = str_replace( $link, $src, $new_image ); } } // We can exit early, to avoid additional parsing. return $new_image; } // Store the original $src to be used later on. $original_src = $src; /** * Filter hook to alter image src at the earliest. * * @param string $src Image src. * @param string $image Image tag. */ $src = apply_filters( 'wp_smush_cdn_before_process_src', $src, $image ); // Make sure this image is inside a supported directory. Try to convert to valid path. if ( $this->cdn_helper->is_supported_url( $src ) ) { $src = $this->process_src( $image, $src, false ); // Replace the src of the image with CDN link. if ( ! empty( $src ) ) { $new_image = preg_replace( '#(src=["|\'])' . $original_src . '(["|\'])#i', '\1' . $src . '\2', $new_image, 1 ); } /** * See if srcset is already set. * * The preg_match is required to make sure that srcset is not already defined. * For the majority of images, srcset will be parsed as part of the wp_calculate_image_srcset filter. * But some images, for example, logos in Avada - will add their own srcset. For such images - generate our own. * * @since 3.9.10 Add 2 new parameters `$original_src, $image` for filter `smush_skip_adding_srcset` to allow user disable auto-resize for specific image. */ if ( ! preg_match( '/srcset=["\'](.*?smushcdn\.com[^"\']+)["\']/i', $image ) ) { if ( $this->cdn_helper->is_dynamic_sizes_active() && ! $this->srcset_helper->skip_adding_srcset( $original_src, $image ) ) { list( $srcset, $sizes ) = $this->generate_srcset( $original_src ); if ( ! is_null( $srcset ) && false !== $srcset ) { // Remove possibly empty srcset attribute. Helpers\Parser::remove_attribute( $new_image, 'srcset' ); Helpers\Parser::add_attribute( $new_image, 'srcset', $srcset ); } if ( ! is_null( $srcset ) && false !== $sizes ) { // Remove possibly empty sizes attribute. Helpers\Parser::remove_attribute( $new_image, 'sizes' ); Helpers\Parser::add_attribute( $new_image, 'sizes', $sizes ); } } else { $data_attributes = array( 'srcset', 'data-srcset' ); foreach ( $data_attributes as $attribute ) { $links = Helpers\Parser::get_attribute( $new_image, $attribute ); $links = Helpers\Parser::get_links_from_content( $links ); if ( isset( $links[0] ) && is_array( $links[0] ) ) { foreach ( $links[0] as $link ) { if ( ! $this->cdn_helper->is_supported_url( $link ) ) { continue; } // Replace the data-envira-srcset of the image with CDN link. $src = $link; $src = $this->cdn_helper->generate_cdn_url( $src ); if ( $src ) { // Replace the src of the image with CDN link. $new_image = str_replace( $link, $src, $new_image ); } } } } } } } // Support for 3rd party lazy loading plugins. $lazy_attributes = array( 'data-src', 'data-lazy-src', 'data-lazyload', 'data-original' ); foreach ( $lazy_attributes as $attr ) { $data_src = Helpers\Parser::get_attribute( $new_image, $attr ); if ( $this->cdn_helper->is_supported_url( $data_src ) ) { $cdn_image = $this->process_src( $image, $data_src ); Helpers\Parser::remove_attribute( $new_image, $attr ); Helpers\Parser::add_attribute( $new_image, $attr, $cdn_image ); } } /** * Filter hook to alter image tag before replacing the image in content. * * @param string $image Image tag. */ return apply_filters( 'smush_cdn_image_tag', $new_image ); } /** * Parse background image for CDN. * * @param string $src Image URL. * @param string $image Image tag (<img>). * * @return string * @since 3.2.2 * */ public function parse_background_image( $src, $image ) { /** * Filter to skip a single image from cdn. * * @param bool $skip Should skip? Default: false. * @param string $src Image url. * @param array|bool $image Image tag or false. */ if ( apply_filters( 'smush_skip_background_image_from_cdn', false, $src, $image ) ) { return $image; } $new_image = $image; // Store the original $src to be used later on. $original_src = $src; /** * Filter hook to alter background image src at the earliest. * * @param string $src Image src. * @param string $image Image tag. */ $src = apply_filters( 'smush_cdn_before_process_background_src', $src, $image ); // Make sure this image is inside a supported directory. Try to convert to valid path. if ( $this->cdn_helper->is_supported_url( $src ) ) { $src = $this->process_src( $image, $src ); // Replace the src of the image with CDN link. if ( ! empty( $src ) ) { $new_image = str_replace( $original_src, $src, $new_image ); } } /** * Filter hook to alter image tag before replacing the background image in content. * * @param string $image Image tag. */ return apply_filters( 'smush_cdn_bg_image_tag', $new_image ); } /** * Process src link and convert to CDN link. * * @param string $image Image tag. * @param string $src Image src attribute. * @param bool $resizing Add resizing arguments. Defaults to true. * We should never add resize arguments to the images from src. But we can and should * add them to the srcset and other possible attributes. * * @return string * @since 3.2.1 * */ private function process_src( $image, $src, $resizing = true ) { $args = array(); // Don't need to auto resize - return default args. if ( $resizing && $this->cdn_helper->is_dynamic_sizes_active() ) { /** * Filter hook to alter image src arguments before going through cdn. * * @param array $args Arguments. * @param string $src Image src. * @param string $image Image tag. */ $args = apply_filters( 'smush_image_cdn_args', array(), $image ); } /** * Filter hook to alter image src before going through cdn. * * @param string $src Image src. * @param string $image Image tag. */ $src = apply_filters( 'smush_image_src_before_cdn', $src, $image ); // Generate cdn url from local url. $src = $this->cdn_helper->generate_cdn_url( $src, $args ); /** * Filter hook to alter image src after replacing with CDN base. * * @param string $src Image src. * @param string $image Image tag. */ return apply_filters( 'smush_image_src_after_cdn', $src, $image ); } public function update_image_srcset_in_ajax( $sources, $size_array, $image_src, $image_meta, $attachment_id = 0 ) { if ( wp_doing_ajax() ) { $sources = $this->update_image_srcset( $sources, $size_array, $image_src, $image_meta, $attachment_id ); } return $sources; } /** * Filters an array of image srcset values, replacing each URL with resized CDN urls. * * Keep the existing srcset sizes if already added by WP, then calculate extra sizes * if required. * * @param array $sources One or more arrays of source data to include in the 'srcset'. * @param array $size_array Array of width and height values in pixels. * @param string $image_src The 'src' of the image. * @param array $image_meta The image metadata as returned by 'wp_get_attachment_metadata()'. * @param int $attachment_id Image attachment ID or 0. * * @return array $sources * @since 3.0 * */ public function update_image_srcset( $sources, $size_array, $image_src, $image_meta, $attachment_id = 0 ) { if ( ! $this->cdn_helper->is_supported_url( $image_src ) || $this->cdn_helper->skip_image_url( $image_src ) ) { return $sources; } if ( empty( $sources ) ) { $width = $size_array[0]; $sources = array( $width => array( 'url' => $image_src, 'descriptor' => 'w', 'value' => $width, ), ); } $main_image_url = $this->get_largest_same_ratio_image_url( $image_src, $size_array, $attachment_id, $image_meta ); foreach ( $sources as $i => $source ) { if ( ! $this->is_valid_url( $source['url'] ) || $this->cdn_helper->skip_image_url( $source['url'] ) ) { continue; } list( $width, $height ) = $this->get_size_from_file_name( $source['url'] ); // The file already has a resized version as a thumbnail. if ( 'w' === $source['descriptor'] && $width === (int) $source['value'] ) { $sources[ $i ]['url'] = $this->cdn_helper->generate_cdn_url( $source['url'] ); continue; } // If don't have attachment id, get original image by removing dimensions from url. if ( empty( $url ) ) { $url = $this->urls_utils->get_url_without_dimensions( $source['url'] ); } $args = array(); // If we got size from url, add them. if ( ! empty( $width ) && ! empty( $height ) ) { // Set size arg. $args = array( 'size' => "{$width}x{$height}", ); } // Replace with CDN url. $sources[ $i ]['url'] = $this->cdn_helper->generate_cdn_url( $url, $args ); } // Set additional sizes if required. $should_add_additional_srcset = $this->cdn_helper->is_dynamic_sizes_active(); if ( $should_add_additional_srcset ) { $sources = $this->set_additional_srcset( $sources, $size_array, $main_image_url, $image_meta, $image_src ); } return $sources; } private function get_largest_same_ratio_image_url( $image_src, $size_array, $attachment_id, $image_meta = array() ) { if ( ! $attachment_id || ! is_array( $size_array ) || count( $size_array ) < 2 ) { return $image_src; } list( $original_width, $original_height ) = $size_array; if ( ! $original_width || ! $original_height ) { return $image_src; } $original_ratio = round( $original_width / $original_height, 4 ); $media_item = $this->media_item_cache->get( $attachment_id ); $prev_area = 0; $selected_url = $image_src; foreach ( $media_item->get_sizes() as $size ) { $width = $size->get_width(); $height = $size->get_height(); if ( ! $width || ! $height ) { continue; } $area = $width * $height; $ratio = round( $width / $height, 4 ); if ( $area > $prev_area && wp_fuzzy_number_match( $ratio, $original_ratio, 0.1 ) ) { $selected_url = $size->get_file_url(); $prev_area = $area; } } return $selected_url; } /** * Add resize arguments to content image src. * * @param array $args Current arguments. * @param object $image Image tag object from DOM. * * @return array $args * @since 3.0 * */ public function update_cdn_image_src_args( $args, $image ) { $dimensions = $this->cdn_helper->guess_dimensions_from_image_markup( $image ); if ( $dimensions ) { $args['size'] = $dimensions; } return $args; } /** * Process CDN status. * * @param array|WP_Error $status Status in JSON format. * * @return stdClass|WP_Error * @since 3.0 * @since 3.1 Moved from Ajax class. * */ public function process_cdn_status( $status ) { if ( is_wp_error( $status ) ) { return $status; } $status = json_decode( $status['body'] ); // Too many requests. if ( is_null( $status ) ) { return new WP_Error( 'too_many_requests', __( 'Too many requests, please try again in a moment.', 'wp-smushit' ) ); } // Some other error from API. if ( ! $status->success ) { return new WP_Error( $status->data->error_code, $status->data->message ); } return $status->data; } /** * Filters the API response. * * Allows modification of the response data after inserting * embedded data (if any) and before echoing the response data. * * @param array $response Response data to send to the client. * * @return array * @since 3.6.0 * */ public function filter_rest_api_response( $response ) { if ( ! $this->settings->get( 'rest_api_support' ) ) { return $response; } if ( ! is_array( $response ) || ! isset( $response['content']['rendered'] ) ) { return $response; } $images = Helpers\Parser::get_links_from_content( $response['content']['rendered'] ); if ( ! isset( $images[0] ) || empty( $images[0] ) ) { return $response; } foreach ( $images[0] as $key => $image ) { if ( ! $this->cdn_helper->is_supported_url( $image ) ) { continue; } // Replace the data-envira-srcset of the image with CDN link. $image = $this->cdn_helper->generate_cdn_url( $image ); if ( $image ) { // Replace the src of the image with CDN link. $response['content']['rendered'] = str_replace( $images[0][ $key ], $image, $response['content']['rendered'] ); } } return $response; } /************************************** * * PRIVATE METHODS * * Functions that are used by the public methods of this CDN class. * * @since 3.0.0: * * @see is_valid_url() * @see get_size_from_file_name() * @see get_url_without_dimensions() * @see set_additional_srcset() * @see generate_srcset() * @see maybe_generate_srcset() * @see is_supported_path() */ /** * Check if we can use the image URL in CDN. * * @param string $url Image URL. * * @return bool * @since 3.0 * */ private function is_valid_url( $url ) { $parsed_url = wp_parse_url( $url ); if ( ! $parsed_url ) { return false; } // No host or path found. if ( ! isset( $parsed_url['host'] ) || ! isset( $parsed_url['path'] ) ) { return false; } // If not supported extension - return false. if ( ! in_array( strtolower( pathinfo( $parsed_url['path'], PATHINFO_EXTENSION ) ), $this->supported_extensions, true ) ) { return false; } return true; } /** * Try to determine height and width from strings WP appends to resized image filenames. * * @param string $src The image URL. * * @return array An array consisting of width and height. * @since 3.0 * */ private function get_size_from_file_name( $src ) { $size = array(); if ( preg_match( '/-(\d+)x(\d+)\.(?:' . implode( '|', $this->supported_extensions ) . ')$/i', $src, $size ) ) { // Get size and width. $width = (int) $size[1]; $height = (int) $size[2]; // Handle retina images. if ( strpos( $src, '@2x' ) ) { $width = 2 * $width; $height = 2 * $height; } // Return width and height as array. if ( $width && $height ) { return array( $width, $height ); } } return array( false, false ); } /** * Filters an array of image srcset values, and add additional values. * * @param array $sources An array of image urls and widths. * @param array $size_array Array of width and height values in pixels. * @param string $url Image URL. * @param array $image_meta The image metadata. * @param string $image_src The src of the image. * * @return array $sources * @since 3.0 * */ private function set_additional_srcset( $sources, $size_array, $url, $image_meta, $image_src = '' ) { $content_width = $this->settings->max_content_width(); // If url is empty, try to get from src. if ( empty( $url ) ) { $url = $this->urls_utils->get_url_without_dimensions( $image_src ); } // We need to add additional dimensions. $full_width = $image_meta['width']; $full_height = $image_meta['height']; $current_width = $size_array[0]; $current_height = $size_array[1]; // Get width and height calculated by WP. list( $constrained_width, $constrained_height ) = wp_constrain_dimensions( $full_width, $full_height, $current_width, $current_height ); // Calculate base width. // If $constrained_width sizes are smaller than current size, set maximum content width. if ( abs( $constrained_width - $current_width ) <= 1 && abs( $constrained_height - $current_height ) <= 1 ) { $base_width = $content_width; } else { $base_width = $current_width; } $current_widths = array_keys( $sources ); $new_sources = array(); /** * Filter to add/update/bypass additional srcsets. * * If empty value or false is retured, additional srcset * will not be generated. * * @param array|bool $additional_multipliers Additional multipliers. */ $additional_multipliers = apply_filters( 'smush_srcset_additional_multipliers', array( 0.2, 0.4, 0.6, 0.8, 1, 1.5, 2, 3, ) ); // Continue only if additional multipliers found or not skipped. // Filter already documented in class-cdn.php. if ( $this->cdn_helper->skip_image_url( $url, false ) || empty( $additional_multipliers ) ) { return $sources; } // Loop through each multipliers and generate image. foreach ( $additional_multipliers as $multiplier ) { // New width by multiplying with original size. $new_width = (int) ( $base_width * $multiplier ); // In most cases - going over the current width is not recommended and probably not what the user is expecting. if ( $new_width > $current_width ) { continue; } // If a nearly sized image already exist, skip. foreach ( $current_widths as $_width ) { // If +- 50 pixel difference - skip. if ( abs( $_width - $new_width ) < 50 || ( $new_width > $full_width ) ) { continue 2; } } // We need the width as well... $dimensions = wp_constrain_dimensions( $current_width, $current_height, $new_width ); // Arguments for cdn url. $args = array( 'size' => "{$new_width}x{$dimensions[1]}", ); // Add new srcset item. $new_sources[ $new_width ] = array( 'url' => $this->cdn_helper->generate_cdn_url( $url, $args ), 'descriptor' => 'w', 'value' => $new_width, ); } // Assign new srcset items to existing ones. if ( ! empty( $new_sources ) ) { // Loop through each items and replace/add. foreach ( $new_sources as $_width_key => $_width_values ) { $sources[ $_width_key ] = $_width_values; } } return $sources; } /** * Try to generate the srcset for the image. * * @param string $src Image source. * * @return array|bool * @since 3.0 * */ public function generate_srcset( $src, $attachment_id = 0, $width = 0, $height = 0 ) { $priority = $this->get_cdn_srcset_priority(); add_filter( 'wp_calculate_image_srcset', array( $this, 'update_image_srcset' ), $priority, 5 ); list( $srcset, $sizes ) = $this->srcset_helper->generate_srcset_and_sizes( $src, $attachment_id, $width, $height ); remove_filter( 'wp_calculate_image_srcset', array( $this, 'update_image_srcset' ), $priority ); return array( $srcset, $sizes ); } /** * @return int */ private function get_cdn_srcset_priority(): int { return defined( 'WP_SMUSH_CDN_DELAY_SRCSET' ) && WP_SMUSH_CDN_DELAY_SRCSET ? 1000 : 99; } }
/home/batcwwjx/./public_html/wp-content/plugins/wp-smushit/core/cdn/class-cdn-srcset-controller.php