get_uncompressed_images_count(); $uncompressed_pages = ceil( $uncompressed_count / self::$MEDIA_PER_PAGE ); $total_count = self::$SqueezeHelpers->get_total_images_count(); $total_pages = ceil( $total_count / self::$MEDIA_PER_PAGE ); $compressed_count = $total_count - $uncompressed_count; $compressed_percentage = ( $total_count > 0 ? round( $compressed_count / $total_count * 100, 2 ) : 0 ); //$total_count = array_sum((array)wp_count_attachments("image")); $not_compressed_posts = implode( ",", self::$SqueezeHelpers->get_uncompressed_images() ); $all_posts = implode( ",", self::$SqueezeHelpers->get_total_images() ); $directory_path = ( get_transient( 'squeeze_bulk_path' ) ? get_transient( 'squeeze_bulk_path' ) : array('/wp-content/uploads/') ); $directory_path = array_map( array(self::$SqueezeHelpers, 'normalize_bulk_directory_storage_path'), (array) $directory_path ); $directory_path_json = wp_json_encode( $directory_path ); $is_direct_webp = self::$SqueezeHelpers->get_option( 'direct_webp' ); ?>

(change)', 'squeeze' ), esc_url( admin_url( 'options-general.php?page=squeeze#squeeze_basic' ) ) ); ?>

%
/

1 ) { ?>

apache_get_modules(); // Only warn when PHP can list modules and mod_rewrite is missing. null means // undetectable (CGI/FPM) — do not treat that as "mod_rewrite off". if ( is_array( $modules ) && !in_array( 'mod_rewrite', $modules, true ) ) { $is_auto_webp = self::$SqueezeHelpers->get_option( 'auto_webp' ); $is_webp_replace_urls = self::$SqueezeHelpers->get_option( 'webp_replace_urls' ); if ( $is_auto_webp && !$is_webp_replace_urls ) { add_settings_error( 'squeeze_notices', 'squeeze_notices', __( 'The Apache mod_rewrite module is not enabled on your server OR your server is not running Apache.', 'squeeze' ) . '
' . __( 'To serve WebP, enable mod_rewrite, or switch to "Rewrite src to WebP URLs in HTML" delivery.', 'squeeze' ), 'warning' ); } } } public function options_page_html() { // check user capabilities if ( !current_user_can( 'manage_options' ) ) { return; } ?>

render_webp_delivery_field(); ?>

setting_jpeg_desc(); ?>

setting_jpeg_advanced_desc(); ?>

setting_png_desc(); ?>

setting_webp_desc(); ?>

setting_avif_desc(); ?>

' . esc_html__( 'Documentation for Squeeze plugin.', 'squeeze' ) . '

'; ?>

setting_upgrade_desc(); ?>
<?php 
            echo esc_attr( $feature[1] );
            ?>

get_option( 'auto_webp' ); $webp_lossless = self::$SqueezeHelpers->get_option( 'webp_lossless' ); register_setting( 'squeeze_options', 'squeeze_options', [$this, 'options_validate'] ); add_settings_section( 'squeeze_basic_quick', '', '__return_false', 'squeeze_options' ); add_settings_field( 'squeeze_setting_auto_compress', __( 'Squeeze on upload', 'squeeze' ) . self::$SqueezeHelpers->get_hint( __( 'Compresses images in the browser before they are uploaded.', 'squeeze' ) ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_basic_quick', array( 'label_for' => 'auto_compress', 'class' => 'squeeze_setting_auto_compress squeeze-settings-row', 'type' => 'checkbox', ) ); add_settings_field( 'squeeze_setting_backup_original', __( 'Backup original image', 'squeeze' ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_basic_quick', array( 'label_for' => 'backup_original', 'class' => 'squeeze_setting_backup_original squeeze-settings-row', 'type' => 'checkbox', ) ); add_settings_field( 'squeeze_setting_clear_data_on_uninstall', __( 'Delete plugin data on uninstall', 'squeeze' ) . self::$SqueezeHelpers->get_hint( __( 'When enabled, uninstalling Squeeze removes its settings, stats, and compression status metadata. Image files are never deleted.', 'squeeze' ) ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_basic_quick', array( 'label_for' => 'clear_data_on_uninstall', 'class' => 'squeeze_setting_clear_data_on_uninstall squeeze-settings-row', 'type' => 'checkbox', ) ); add_settings_field( 'squeeze_setting_compress_formats', __( 'Image formats', 'squeeze' ) . self::$SqueezeHelpers->get_hint( __( 'Select which image formats you want to be squeezed.', 'squeeze' ) ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_basic_quick', array( 'label_for' => 'compress_formats', 'class' => 'squeeze_setting_compress_formats squeeze-settings-row', 'type' => 'formats_checkbox_group', ) ); add_settings_section( 'squeeze_basic_webp', '', '__return_false', 'squeeze_options' ); add_settings_section( 'squeeze_basic_thumbs', '', '__return_false', 'squeeze_options' ); add_settings_field( 'squeeze_setting_compress_thumbs', __( 'Squeeze thumbnails', 'squeeze' ) . self::$SqueezeHelpers->get_hint( __( 'Choose which image thumbnail sizes you want to squeeze along with the original image.', 'squeeze' ) ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_basic_thumbs', array( 'label_for' => 'compress_thumbs', 'class' => 'squeeze_setting_compress_thumbs squeeze-settings-row', 'type' => 'thumbs_checkbox_group', ) ); add_settings_section( 'squeeze_basic_limits', '', '__return_false', 'squeeze_options' ); add_settings_field( 'squeeze_setting_max_width', __( 'Max. image width', 'squeeze' ) . self::$SqueezeHelpers->get_hint( __( 'Limit a width of an original image. Leave this field empty if you do not want to crop the image by width.', 'squeeze' ) ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_basic_limits', array( 'label_for' => 'max_width', 'class' => 'squeeze_setting_max_width squeeze-settings-row', 'type' => 'placeholder', ) ); add_settings_field( 'squeeze_setting_max_height', __( 'Max. image height', 'squeeze' ) . self::$SqueezeHelpers->get_hint( __( 'Limit a height of an original image. Leave this field empty if you do not want to crop the image by height.', 'squeeze' ) ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_basic_limits', array( 'label_for' => 'max_height', 'class' => 'squeeze_setting_max_height squeeze-settings-row', 'type' => 'placeholder', ) ); add_settings_field( 'squeeze_setting_timeout', __( 'Squeeze timeout', 'squeeze' ) . self::$SqueezeHelpers->get_hint( __( 'Time limit for squeezing an image. If you get an error during image squeezing, try to increase this value.', 'squeeze' ) ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_basic_limits', array( 'label_for' => 'timeout', 'class' => 'squeeze_setting_timeout squeeze-settings-row squeeze-inline-limit', 'type' => 'number', 'units' => 'sec', 'min' => 1, ) ); add_settings_section( 'squeeze_basic_exclusions', '', '__return_false', 'squeeze_options' ); add_settings_field( 'squeeze_setting_excluded_images', __( 'Excluded images', 'squeeze' ) . self::$SqueezeHelpers->get_hint( __( 'Enter a list of images that you want to exclude from squeezing. Both full URLs and partial strings can be used. One URL per line.', 'squeeze' ) ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_basic_exclusions', array( 'label_for' => 'excluded_images', 'class' => 'squeeze_setting_excluded_images squeeze-settings-row', 'type' => 'textarea', ) ); add_settings_section( 'squeeze_basic_hidden', '', '__return_false', 'squeeze_options' ); add_settings_field( 'squeeze_setting_restore_defaults', '', [$this, 'options_callback'], 'squeeze_options', 'squeeze_basic_hidden', array( 'label_for' => 'restore_defaults', 'class' => 'squeeze_setting_restore_defaults', 'type' => 'hidden', ) ); add_settings_section( 'squeeze_jpeg_settings', __( 'JPEG Settings', 'squeeze' ), 'squeeze_setting_jpeg_desc', 'squeeze_options', array( 'section_class' => 'squeeze_jpeg', ) ); add_settings_field( 'squeeze_setting_jpeg_quality', __( 'Quality', 'squeeze' ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_jpeg_settings', array( 'label_for' => 'jpeg_quality', 'class' => 'squeeze_setting_jpeg_quality', 'type' => 'range', ) ); add_settings_field( 'squeeze_setting_jpeg_smoothing', __( 'Smoothing', 'squeeze' ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_jpeg_settings', array( 'label_for' => 'jpeg_smoothing', 'class' => 'squeeze_setting_jpeg_smoothing', 'type' => 'range', ) ); add_settings_field( 'squeeze_setting_jpeg_baseline', __( 'Pointless spec compliance', 'squeeze' ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_jpeg_advanced_settings', array( 'label_for' => 'jpeg_baseline', 'class' => 'squeeze_setting_jpeg_baseline', 'type' => 'checkbox', ) ); // deactivated, because throws error when enabled //add_settings_field('squeeze_setting_jpeg_arithmetic', __('Arithmetic', 'squeeze'), [$this, 'options_callback'], 'squeeze_options', 'squeeze_jpeg_advanced_settings', array('label_for' => 'jpeg_arithmetic', 'class' => 'squeeze_setting_jpeg_arithmetic', 'type' => 'checkbox')); add_settings_field( 'squeeze_setting_jpeg_progressive', __( 'Progressive rendering', 'squeeze' ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_jpeg_advanced_settings', array( 'label_for' => 'jpeg_progressive', 'class' => 'squeeze_setting_jpeg_progressive', 'type' => 'checkbox', ) ); add_settings_field( 'squeeze_setting_jpeg_optimize_coding', __( 'Optimize Huffman table', 'squeeze' ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_jpeg_advanced_settings', array( 'label_for' => 'jpeg_optimize_coding', 'class' => 'squeeze_setting_jpeg_optimize_coding', 'type' => 'checkbox', ) ); add_settings_field( 'squeeze_setting_jpeg_color_space', __( 'Channels', 'squeeze' ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_jpeg_advanced_settings', array( 'label_for' => 'jpeg_color_space', 'class' => 'squeeze_setting_jpeg_color_space', 'type' => 'select', 'options' => array( '3' => 'YCbCr', '1' => 'Grayscale', '2' => 'RGB', ), ) ); add_settings_field( 'squeeze_setting_jpeg_quant_table', __( 'Quantization', 'squeeze' ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_jpeg_advanced_settings', array( 'label_for' => 'jpeg_quant_table', 'class' => 'squeeze_setting_jpeg_quant_table', 'type' => 'select', 'options' => array( '0' => 'JPEG Annex K', '1' => 'Flat', '2' => 'MSSIM-tuned Kodak', '3' => 'ImageMagick', '4' => 'PSNR-HVS-M-tuned Kodak', '5' => 'Klein et al', '6' => 'Watson et al', '7' => 'Ahumada et al', '8' => 'Peterson et al', ), ) ); add_settings_field( 'squeeze_setting_jpeg_trellis_multipass', __( 'Trellis multipass', 'squeeze' ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_jpeg_advanced_settings', array( 'label_for' => 'jpeg_trellis_multipass', 'class' => 'squeeze_setting_jpeg_trellis_multipass', 'type' => 'checkbox', ) ); add_settings_field( 'squeeze_setting_jpeg_trellis_opt_zero', __( 'Optimize zero block runs', 'squeeze' ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_jpeg_advanced_settings', array( 'label_for' => 'jpeg_trellis_opt_zero', 'class' => 'squeeze_setting_jpeg_trellis_opt_zero', 'type' => 'checkbox', ) ); add_settings_field( 'squeeze_setting_jpeg_trellis_opt_table', __( 'Optimize after trellis quantization', 'squeeze' ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_jpeg_advanced_settings', array( 'label_for' => 'jpeg_trellis_opt_table', 'class' => 'squeeze_setting_jpeg_trellis_opt_table', 'type' => 'checkbox', ) ); add_settings_field( 'squeeze_setting_jpeg_trellis_loops', __( 'Trellis quantization passes', 'squeeze' ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_jpeg_advanced_settings', array( 'label_for' => 'jpeg_trellis_loops', 'class' => 'squeeze_setting_jpeg_trellis_loops', 'type' => 'range', 'min' => 1, 'max' => 50, ) ); add_settings_field( 'squeeze_setting_jpeg_auto_subsample', __( 'Auto subsample chroma', 'squeeze' ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_jpeg_advanced_settings', array( 'label_for' => 'jpeg_auto_subsample', 'class' => 'squeeze_setting_jpeg_auto_subsample', 'type' => 'checkbox', ) ); add_settings_field( 'squeeze_setting_jpeg_chroma_subsample', __( 'Subsample chroma by', 'squeeze' ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_jpeg_advanced_settings', array( 'label_for' => 'jpeg_chroma_subsample', 'class' => 'squeeze_setting_jpeg_chroma_subsample', 'type' => 'range', 'min' => 1, 'max' => 4, ) ); add_settings_field( 'squeeze_setting_jpeg_separate_chroma_quality', __( 'Separate chroma quality', 'squeeze' ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_jpeg_advanced_settings', array( 'label_for' => 'jpeg_separate_chroma_quality', 'class' => 'squeeze_setting_jpeg_separate_chroma_quality', 'type' => 'checkbox', ) ); add_settings_field( 'squeeze_setting_jpeg_chroma_quality', __( 'Chroma quality', 'squeeze' ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_jpeg_advanced_settings', array( 'label_for' => 'jpeg_chroma_quality', 'class' => 'squeeze_setting_jpeg_chroma_quality', 'type' => 'range', ) ); add_settings_section( 'squeeze_png_settings', __( 'PNG Settings', 'squeeze' ), 'squeeze_setting_png_desc', 'squeeze_options', array( 'section_class' => 'squeeze_png', ) ); add_settings_field( 'squeeze_setting_png_quality', __( 'Quality', 'squeeze' ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_png_settings', array( 'label_for' => 'png_quality', 'class' => 'squeeze_setting_png_quality', 'type' => 'range', 'min' => 0.01, 'max' => 1, 'step' => 0.01, ) ); add_settings_section( 'squeeze_webp_settings', __( 'WEBP Settings', 'squeeze' ), 'squeeze_setting_webp_desc', 'squeeze_options', array( 'section_class' => 'squeeze_webp', ) ); add_settings_field( 'squeeze_setting_webp_method', __( 'Effort', 'squeeze' ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_webp_settings', array( 'label_for' => 'webp_method', 'class' => 'squeeze_setting_webp_method', 'type' => 'range', 'min' => 0, 'max' => 6, ) ); add_settings_field( 'squeeze_setting_webp_quality', __( 'Quality', 'squeeze' ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_webp_settings', array( 'label_for' => 'webp_quality', 'class' => 'squeeze_setting_webp_quality', 'type' => 'range', 'min' => 0, 'max' => 100, 'hidden' => ( $webp_lossless ? true : '' ), ) ); add_settings_field( 'squeeze_setting_webp_lossless', __( 'Lossless', 'squeeze' ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_webp_settings', array( 'label_for' => 'webp_lossless', 'class' => 'squeeze_setting_webp_lossless', 'type' => 'checkbox', ) ); add_settings_field( 'squeeze_setting_webp_near_lossless', __( 'Near lossless', 'squeeze' ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_webp_settings', array( 'label_for' => 'webp_near_lossless', 'class' => 'squeeze_setting_webp_near_lossless', 'type' => 'range', 'min' => 0, 'max' => 100, ) ); add_settings_section( 'squeeze_avif_settings', __( 'AVIF Settings', 'squeeze' ), 'squeeze_setting_avif_desc', 'squeeze_options', array( 'section_class' => 'squeeze_avif', ) ); add_settings_field( 'squeeze_setting_avif_cqLevel', __( 'Quality', 'squeeze' ), [$this, 'options_callback'], 'squeeze_options', 'squeeze_avif_settings', array( 'label_for' => 'avif_cqLevel', 'class' => 'squeeze_setting_avif_cqLevel', 'type' => 'range', 'min' => 1, 'max' => 100, ) ); } /** * Map stored options to a single WebP delivery mode for the settings UI. * * @param array $options squeeze_options array. * @return string direct|sidecar|sidecar_replace (internal keys; UI labels use "Separate WebP folder".) */ protected function get_webp_delivery_mode( $options ) { $direct = !empty( $options['direct_webp'] ); $auto = !empty( $options['auto_webp'] ); $replace = !empty( $options['webp_replace_urls'] ); if ( $direct ) { return 'direct'; } if ( $auto && $replace ) { return 'sidecar_replace'; } if ( $auto ) { return 'sidecar'; } return 'direct'; } /** * Unified WebP delivery control (radios + collapsible examples). */ public function render_webp_delivery_field() { $options = get_option( 'squeeze_options' ); if ( !is_array( $options ) ) { $options = array(); } $mode = $this->get_webp_delivery_mode( $options ); $advanced_open = 'direct' !== $mode; ?>
>

src to WebP URLs in HTML', 'squeeze' ); ?>

<img src="//yoursite.example/wp-content/uploads/2025/07/photo.jpg" alt="…" />


<img src="//yoursite.example/wp-content/squeeze-webp/uploads/2025/07/photo.jpg.webp" alt="…" />

<img src="//yoursite.example/wp-content/uploads/2025/07/photo.jpg" alt="…" />




/wp-content/uploads/2025/07/image.jpg                    ~500 KB  
/wp-content/squeeze-webp/uploads/2025/07/image.jpg.webp    ~50 KB  


/wp-content/uploads/2025/07/image.jpg           ~500 KB
/wp-content/uploads/2025/07/image-300x300.jpg   ~230 KB


/wp-content/uploads/2025/07/image.webp          ~50 KB
/wp-content/uploads/2025/07/image-300x300.webp  ~20 KB
get_webp_delivery_mode( $options ); $mode_label = __( 'Direct WebP', 'squeeze' ); if ( 'sidecar' === $mode ) { $mode_label = __( 'Keep JPEG/PNG URLs — server serves WebP', 'squeeze' ); } elseif ( 'sidecar_replace' === $mode ) { $mode_label = __( 'Rewrite src to WebP URLs in HTML', 'squeeze' ); } $upload_on = !empty( $options['auto_compress'] ); $backup_on = !empty( $options['backup_original'] ); ?>

' . esc_html( $mode_label ) . ''); if ( $upload_on ) { $profile_bits[] = esc_html__( 'Squeeze on upload', 'squeeze' ); } if ( $backup_on ) { $profile_bits[] = esc_html__( 'Backup on', 'squeeze' ); } echo '

' . wp_kses( implode( ' · ', $profile_bits ), array( 'strong' => array(), ) ) . '

'; ?>

get_webp_delivery_mode( $previous_options ); if ( isset( $input['webp_delivery_mode'] ) && is_string( $input['webp_delivery_mode'] ) ) { $mode = sanitize_text_field( wp_unslash( $input['webp_delivery_mode'] ) ); unset($input['webp_delivery_mode']); switch ( $mode ) { case 'sidecar': case 'sidecar_picture': $input['direct_webp'] = false; $input['auto_webp'] = true; $input['webp_replace_urls'] = false; break; case 'sidecar_replace': $input['direct_webp'] = false; $input['auto_webp'] = true; $input['webp_replace_urls'] = true; break; case 'direct': default: $input['direct_webp'] = true; $input['auto_webp'] = false; $input['webp_replace_urls'] = false; break; } } $input['jpeg_quality'] = absint( $input['jpeg_quality'] ); $input['jpeg_smoothing'] = ( isset( $input['jpeg_smoothing'] ) ? absint( $input['jpeg_smoothing'] ) : self::$SqueezeHelpers->get_default_value( 'jpeg_smoothing' ) ); $input['jpeg_color_space'] = ( isset( $input['jpeg_color_space'] ) ? absint( $input['jpeg_color_space'] ) : self::$SqueezeHelpers->get_default_value( 'jpeg_color_space' ) ); $input['jpeg_quant_table'] = ( isset( $input['jpeg_quant_table'] ) ? absint( $input['jpeg_quant_table'] ) : self::$SqueezeHelpers->get_default_value( 'jpeg_quant_table' ) ); $input['jpeg_trellis_loops'] = ( isset( $input['jpeg_trellis_loops'] ) ? absint( $input['jpeg_trellis_loops'] ) : self::$SqueezeHelpers->get_default_value( 'jpeg_trellis_loops' ) ); $input['jpeg_chroma_subsample'] = ( isset( $input['jpeg_chroma_subsample'] ) ? absint( $input['jpeg_chroma_subsample'] ) : self::$SqueezeHelpers->get_default_value( 'jpeg_chroma_subsample' ) ); $input['jpeg_chroma_quality'] = ( isset( $input['jpeg_chroma_quality'] ) ? absint( $input['jpeg_chroma_quality'] ) : self::$SqueezeHelpers->get_default_value( 'jpeg_chroma_quality' ) ); $input['png_level'] = ( isset( $input['png_level'] ) ? absint( $input['png_level'] ) : self::$SqueezeHelpers->get_default_value( 'png_level' ) ); $input['png_quality'] = ( isset( $input['png_quality'] ) ? floatval( $input['png_quality'] ) : self::$SqueezeHelpers->get_default_value( 'png_quality' ) ); $input['webp_method'] = ( isset( $input['webp_method'] ) ? absint( $input['webp_method'] ) : self::$SqueezeHelpers->get_default_value( 'webp_method' ) ); $input['webp_quality'] = ( isset( $input['webp_quality'] ) ? absint( $input['webp_quality'] ) : self::$SqueezeHelpers->get_default_value( 'webp_quality' ) ); $input['webp_near_lossless'] = ( isset( $input['webp_near_lossless'] ) ? absint( $input['webp_near_lossless'] ) : self::$SqueezeHelpers->get_default_value( 'webp_near_lossless' ) ); $input['avif_cqLevel'] = ( isset( $input['avif_cqLevel'] ) ? absint( $input['avif_cqLevel'] ) : self::$SqueezeHelpers->get_default_value( 'avif_cqLevel' ) ); $input['jpeg_baseline'] = ( isset( $input['jpeg_baseline'] ) ? boolval( $input['jpeg_baseline'] ) : '0' ); //$input[ 'jpeg_arithmetic' ] = isset($input[ 'jpeg_arithmetic' ]) ? boolval($input[ 'jpeg_arithmetic' ]) : '0'; $input['jpeg_progressive'] = ( isset( $input['jpeg_progressive'] ) ? boolval( $input['jpeg_progressive'] ) : '0' ); $input['jpeg_optimize_coding'] = ( isset( $input['jpeg_optimize_coding'] ) ? boolval( $input['jpeg_optimize_coding'] ) : '0' ); $input['jpeg_trellis_multipass'] = ( isset( $input['jpeg_trellis_multipass'] ) ? boolval( $input['jpeg_trellis_multipass'] ) : '0' ); $input['jpeg_trellis_opt_zero'] = ( isset( $input['jpeg_trellis_opt_zero'] ) ? boolval( $input['jpeg_trellis_opt_zero'] ) : '0' ); $input['jpeg_trellis_opt_table'] = ( isset( $input['jpeg_trellis_opt_table'] ) ? boolval( $input['jpeg_trellis_opt_table'] ) : '0' ); $input['jpeg_auto_subsample'] = ( isset( $input['jpeg_auto_subsample'] ) ? boolval( $input['jpeg_auto_subsample'] ) : '0' ); $input['jpeg_separate_chroma_quality'] = ( isset( $input['jpeg_separate_chroma_quality'] ) ? boolval( $input['jpeg_separate_chroma_quality'] ) : '0' ); $input['png_interlace'] = ( isset( $input['png_interlace'] ) ? boolval( $input['png_interlace'] ) : '0' ); $input['webp_lossless'] = ( isset( $input['webp_lossless'] ) ? boolval( $input['webp_lossless'] ) : '0' ); $input['auto_compress'] = ( isset( $input['auto_compress'] ) ? boolval( $input['auto_compress'] ) : '0' ); // TBD: maybe get default value from the database $input['auto_webp'] = ( isset( $input['auto_webp'] ) ? boolval( $input['auto_webp'] ) : '0' ); $input['webp_replace_urls'] = ( isset( $input['webp_replace_urls'] ) && $input['auto_webp'] ? boolval( $input['webp_replace_urls'] ) : '0' ); $input['direct_webp'] = ( isset( $input['direct_webp'] ) ? boolval( $input['direct_webp'] ) : '0' ); $new_webp_mode = $this->get_webp_delivery_mode( $input ); if ( $previous_webp_mode !== $new_webp_mode ) { add_settings_error( 'squeeze_notices', 'webp_delivery_mode_changed', __( 'WebP delivery mode changed. Existing files are not migrated automatically — re-squeeze images after switching. Leftover JPEG/PNG + WebP pairs or orphaned files under squeeze-webp may remain until cleaned up.', 'squeeze' ), 'warning' ); } if ( isset( $input['cdn_url'] ) ) { $cdn_raw = trim( wp_unslash( (string) $input['cdn_url'] ) ); $input['cdn_url'] = ( $cdn_raw === '' ? '' : esc_url_raw( $cdn_raw ) ); } else { $input['cdn_url'] = ''; } $input['backup_original'] = ( isset( $input['backup_original'] ) ? boolval( $input['backup_original'] ) : '0' ); $input['clear_data_on_uninstall'] = ( isset( $input['clear_data_on_uninstall'] ) ? boolval( $input['clear_data_on_uninstall'] ) : '0' ); $input['compress_formats'] = ( isset( $input['compress_formats'] ) && is_array( $input['compress_formats'] ) ? $this->validate_image_formats( $input['compress_formats'], $input['direct_webp'] ) : array() ); $input['compress_thumbs'] = ( isset( $input['compress_thumbs'] ) && is_array( $input['compress_thumbs'] ) ? $input['compress_thumbs'] : array() ); $input['max_width'] = ( isset( $input['max_width'] ) && $input['max_width'] > 0 ? absint( $input['max_width'] ) : '' ); $input['max_height'] = ( isset( $input['max_height'] ) && $input['max_height'] > 0 ? absint( $input['max_height'] ) : '' ); $input['excluded_images'] = ( isset( $input['excluded_images'] ) ? $input['excluded_images'] : '' ); $input['timeout'] = ( isset( $input['timeout'] ) && $input['timeout'] > 0 ? absint( $input['timeout'] ) : 1 ); $input['restore_defaults'] = ( isset( $input['restore_defaults'] ) ? $input['restore_defaults'] : '0' ); if ( !isset( $input['restore_defaults'] ) || $input['restore_defaults'] !== '1' ) { add_settings_error( 'squeeze_notices', 'settings_updated', __( 'Settings have been updated.', 'squeeze' ), 'success' ); } unset($input['webp_picture_markup']); return $input; } protected function validate_image_formats( $input, $is_direct_webp = false ) { $formats = self::ALLOWED_IMAGE_FORMATS; if ( !isset( $input ) || !is_array( $input ) ) { return array(); } // remove all formats that are not in the allowed formats list $input = array_filter( $input, function ( $format ) use($formats) { //check by key return array_key_exists( $format, $formats ); }, ARRAY_FILTER_USE_KEY ); // if direct webp conversion is enabled, webp format is mandatory if ( $is_direct_webp && !array_key_exists( 'webp', $input ) ) { $input['webp'] = 'on'; } return $input; } public function options_callback( $args ) { $label_for = ( isset( $args['label_for'] ) ? $args['label_for'] : '' ); if ( empty( $label_for ) ) { return; } $type = ( isset( $args['type'] ) ? $args['type'] : 'text' ); $class = ( isset( $args['class'] ) ? $args['class'] : '' ); $default = self::$SqueezeHelpers->get_default_value( $label_for ); $options = get_option( 'squeeze_options' ); $is_hidden = ( isset( $args['hidden'] ) && $args['hidden'] ? 'hidden' : '' ); $extra_classes = []; if ( $is_hidden ) { $extra_classes[] = 'squeeze-hidden'; } $extra_classes = implode( ' ', $extra_classes ); switch ( $type ) { case 'text': $value = ( isset( $options[$label_for] ) ? $options[$label_for] : $default ); $placeholder = ( isset( $args['placeholder'] ) ? $args['placeholder'] : '' ); echo ""; break; case 'number': $value = ( isset( $options[$label_for] ) ? $options[$label_for] : $default ); $units = ( isset( $args['units'] ) ? $args['units'] : '' ); $min = ( isset( $args['min'] ) ? $args['min'] : '' ); $max = ( isset( $args['max'] ) ? $args['max'] : '' ); echo ""; if ( $units ) { echo "" . esc_html( $units ) . ""; } break; case 'range': $value = ( isset( $options[$label_for] ) ? $options[$label_for] : $default ); $min = ( isset( $args['min'] ) ? $args['min'] : 0 ); $max = ( isset( $args['max'] ) ? $args['max'] : 100 ); $step = ( isset( $args['step'] ) ? $args['step'] : 1 ); echo ""; echo ''; ?> "; echo ''; break; case 'select': $value = ( isset( $options[$label_for] ) ? $options[$label_for] : $default ); echo ""; break; case 'thumbs_checkbox_group': $thumbs = array(); $value = ( isset( $options[$label_for] ) ? (array) $options[$label_for] : $default ); $available_sizes = wp_get_registered_image_subsizes(); foreach ( $available_sizes as $key => $size ) { $thumbs[$key] = ucwords( str_replace( '_', ' ', $key ) ) . ' (' . $size['width'] . 'x' . $size['height'] . ')'; } // Add the scaled image size option $big_image_size_threshold = apply_filters( 'big_image_size_threshold', 2560 ); $thumbs['full'] = 'Scaled (' . $big_image_size_threshold . 'x' . $big_image_size_threshold . ')'; echo '
'; echo ''; echo ''; echo ''; echo '
'; echo '
'; echo '
'; foreach ( $thumbs as $key => $option ) { echo '
'; echo " "; echo ""; echo '
'; } echo '
'; echo '
'; break; case 'formats_checkbox_group': $is_direct_webp = ( isset( $options['direct_webp'] ) ? (bool) $options['direct_webp'] : false ); $formats = self::ALLOWED_IMAGE_FORMATS; $value = ( isset( $options[$label_for] ) ? (array) $options[$label_for] : $default ); echo '
'; echo '
'; foreach ( $formats as $key => $option ) { echo '
'; echo " "; echo ""; if ( $is_direct_webp && $key === 'webp' ) { echo '' . __( '(mandatory when Direct WebP is enabled)', 'squeeze' ) . ''; } echo '
'; } echo '
'; echo '
'; break; case 'hidden': $value = ( isset( $options[$label_for] ) ? $options[$label_for] : $default ); echo ""; break; case 'textarea': $value = ( isset( $options[$label_for] ) ? $options[$label_for] : $default ); echo ""; break; case 'placeholder': echo '

' . sprintf( __( 'This feature is available only in the premium version.', 'squeeze' ), esc_url( self::$UPGRADE_URL ) ) . '

'; break; } } public function setting_basic_desc() { echo '

' . esc_html__( 'Basic squeezing settings.', 'squeeze' ) . '

'; } public function setting_jpeg_desc() { echo '

' . esc_html__( 'Squeezing settings for JPEG images.', 'squeeze' ) . '

'; } public function setting_jpeg_advanced_desc() { echo '

' . esc_html__( 'More precise settings for experienced users.', 'squeeze' ) . '

'; } public function setting_png_desc() { echo '

' . esc_html__( 'Squeezing settings for PNG images.', 'squeeze' ) . '

'; } public function setting_webp_desc() { echo '

' . esc_html__( 'Squeezing settings for WebP images.', 'squeeze' ) . '

'; } public function setting_avif_desc() { echo '

' . esc_html__( 'Squeezing settings for Avif images.', 'squeeze' ) . '

'; } public function setting_upgrade_desc() { echo '

' . esc_html__( 'Upgrade to premium version for more features.', 'squeeze' ) . '

'; } public function setting_license_desc() { } public function restore_defaults( $old_value, $value ) { if ( isset( $value['restore_defaults'] ) && $value['restore_defaults'] === '1' ) { $result = delete_option( 'squeeze_options', "" ); if ( $result ) { add_settings_error( 'squeeze_notices', 'settings_restored', __( 'Settings have been restored.', 'squeeze' ), 'success' ); } else { add_settings_error( 'squeeze_notices', 'settings_not_restored', __( 'Settings have not been restored.', 'squeeze' ), 'error' ); } } } public function flush_rewrite_rules( $old_value, $value ) { if ( isset( $value['auto_webp'] ) && $value['auto_webp'] !== $old_value['auto_webp'] ) { flush_rewrite_rules(); add_settings_error( 'squeeze_notices', 'rewrite_rules_flushed', __( 'Rewrite rules have been flushed.', 'squeeze' ), 'success' ); } } public function add_custom_field_to_attachment( $form_fields, $post ) { $all_formats = self::ALLOWED_IMAGE_FORMATS; $all_mimes = self::$SqueezeHelpers->get_image_formats( true, $all_formats ); if ( in_array( $post->post_mime_type, $all_mimes ) ) { $selected_mimes = self::$SqueezeHelpers->get_image_formats( true ); $is_compressed = get_post_meta( $post->ID, 'squeeze_is_compressed', true ); $compression_failed = get_post_meta( $post->ID, 'squeeze_compression_failed', true ); $can_restore = self::$SqueezeHelpers->can_restore( $post->ID ); $is_excluded = false; $url = wp_get_original_image_url( $post->ID ); if ( $url ) { $excluded_images = self::$SqueezeHelpers->get_excluded_images(); $is_excluded = self::$SqueezeHelpers->is_excluded_image( $url, $excluded_images ); } $form_fields['squeeze_is_compressed'] = array( 'label' => __( 'Squeeze', 'squeeze' ), 'input' => 'html', 'html' => ( !in_array( $post->post_mime_type, $selected_mimes ) ? ' ' . __( 'Image format is not selected for compression in the plugin settings', 'squeeze' ) . '
' : (( $is_excluded ? ' ' . __( 'Image is excluded from compression', 'squeeze' ) . ' (' . esc_html__( 'found substring: ', 'squeeze' ) . $is_excluded['exclude_reason'] . ')' : (( $compression_failed === 'larger_than_original' ? '

 ' . sprintf( __( 'Could not compress — result was larger than original. Try adjusting compression settings, then re-squeeze.', 'squeeze' ), self::$SETTINGS_URL . '#squeeze_' . pathinfo( get_attached_file( $post->ID ), PATHINFO_EXTENSION ) ) . '

' . (( $can_restore ? '

' : '' )) . '

' : (( $is_compressed ? '

 ' . __( 'Squeezed', 'squeeze' ) . '

' . (( $can_restore ? '

' : '' )) . '

' : '

 ' . __( 'Not squeezed', 'squeeze' ) . '

' )) )) )) ), ); } return $form_fields; } public function add_media_columns( $posts_columns ) { $posts_columns['squeeze'] = __( 'Squeeze', 'squeeze' ); return $posts_columns; } public function media_custom_column( $column_name, $post_id ) { if ( 'squeeze' !== $column_name ) { return; } $form_fields = $this->add_custom_field_to_attachment( array(), get_post( $post_id ) ); if ( $form_fields ) { echo wp_kses_post( $form_fields['squeeze_is_compressed']['html'] ); } } public function sortable_columns( $columns ) { $columns['squeeze'] = 'squeeze'; return $columns; } public function sortable_columns_orderby( $query ) { if ( !is_admin() || !$query->is_main_query() ) { return; } $orderby = $query->get( 'orderby' ); if ( 'squeeze' === $orderby ) { // Define the allowed image formats $allowed_formats = self::$SqueezeHelpers->get_image_formats( true ); // include all media $query->set( 'meta_query', array( 'relation' => 'OR', array( 'key' => 'squeeze_is_compressed', 'compare' => 'NOT EXISTS', ), array( 'key' => 'squeeze_is_compressed', 'compare' => 'EXISTS', ), ) ); // Add the meta_query to filter by specific image formats //$query->set('post_mime_type', $allowed_formats); $query->set( 'orderby', 'meta_value' ); } } public function media_filter_dropdown() { global $wp_query; $post_type = 'attachment'; if ( isset( $_GET['post_type'] ) ) { $post_type = sanitize_text_field( wp_unslash( $_GET['post_type'] ) ); } if ( 'attachment' !== $post_type ) { return; } $selected = ( isset( $_GET['squeeze_filter'] ) ? sanitize_text_field( wp_unslash( $_GET['squeeze_filter'] ) ) : '' ); $options = array( 'all' => __( 'Squeeze: All images', 'squeeze' ), 'non-squeezed' => __( 'Non Squeezed Images', 'squeeze' ), ); echo ''; } public function media_filter_query( $query ) { global $current_screen; if ( !is_admin() || !empty( $current_screen ) && 'upload' !== $current_screen->base || 'attachment' !== $query->get( 'post_type' ) ) { return $query; } if ( isset( $_GET['squeeze_filter'] ) ) { $squeeze_filter = sanitize_text_field( wp_unslash( $_GET['squeeze_filter'] ) ); if ( 'non-squeezed' === $squeeze_filter ) { $query->set( 'meta_query', self::$SqueezeHelpers->get_non_squeezed_media_meta_query() ); $query->set( 'squeeze_exclude_excluded', true ); $query->set( 'orderby', 'meta_value' ); $query->set( 'post_mime_type', self::$SqueezeHelpers->get_image_formats( true ) ); } } return $query; } public function media_filter_ajax_query( $query ) { if ( !isset( $_POST['query']['squeeze_filter'] ) ) { return $query; } $squeeze_filter = sanitize_text_field( wp_unslash( $_POST['query']['squeeze_filter'] ) ); if ( 'non-squeezed' === $squeeze_filter ) { $query['meta_query'] = self::$SqueezeHelpers->get_non_squeezed_media_meta_query(); $query['squeeze_exclude_excluded'] = true; $query['orderby'] = 'meta_value'; $query['post_mime_type'] = self::$SqueezeHelpers->get_image_formats( true ); } return $query; } public function media_filter_exclude_excluded( $posts, $query ) { if ( empty( $posts ) || !$query instanceof \WP_Query ) { return $posts; } if ( !$query->get( 'squeeze_exclude_excluded' ) ) { return $posts; } if ( empty( self::$SqueezeHelpers->get_excluded_images() ) ) { return $posts; } return array_values( array_filter( $posts, function ( $post ) { return !self::$SqueezeHelpers->is_attachment_excluded( $post->ID ); } ) ); } public function handle_excluded_images_option_change( $old_value, $new_value ) { $old_excluded = ( isset( $old_value['excluded_images'] ) ? $old_value['excluded_images'] : '' ); $new_excluded = ( isset( $new_value['excluded_images'] ) ? $new_value['excluded_images'] : '' ); if ( $old_excluded === $new_excluded ) { return; } self::$SqueezeHelpers->clear_excluded_images_cache(); self::$SqueezeHelpers->clear_options_cache(); self::$SqueezeHelpers->invalidate_uncompressed_stats_cache(); } public function svg_sprite_output() { global $pagenow; if ( $pagenow === 'upload.php' && isset( $_GET['page'] ) && $_GET['page'] === 'squeeze-bulk' ) { include self::$PLUGIN_DIR . 'assets/images/sprite.svg'; } } public function add_preview_button_placeholder( $post ) { if ( !wp_attachment_is_image( $post->ID ) ) { return; } echo '
'; echo ''; echo '
'; } public function incompatibility_notices() { // Bail if we're not in the admin or the screen helper isn't available. if ( !is_admin() || !function_exists( 'get_current_screen' ) ) { return; } $screen = get_current_screen(); // List of screen IDs where we want the warning. $target_screens = array( 'settings_page_squeeze', // options-general.php?page=squeeze 'media_page_squeeze-bulk', // upload.php?page=squeeze-bulk 'upload', // the core Media → Library (list table) 'media', // the core Media → Add New 'plugins', ); if ( !$screen || !in_array( $screen->id, $target_screens, true ) ) { return; } // check if webp-express/webp-express.php plugin is active and show a notice if ( is_plugin_active( 'webp-express/webp-express.php' ) ) { ?>

Squeeze plugin.', 'squeeze' ); ?>

Squeeze plugin.', 'squeeze' ); ?>