OwlCyberSecurity - MANAGER
Edit File: class-png2jpg-controller.php
<?php namespace Smush\Core\Png2Jpg; use Smush\Core\Controller; use Smush\Core\File_System; use Smush\Core\Helper; use Smush\Core\Media\Media_Item; use Smush\Core\Media\Media_Item_Cache; use Smush\Core\Settings; use Smush\Core\Stats\Global_Stats; use Smush\Core\Stats\Media_Item_Optimization_Global_Stats_Persistable; use Smush\Core\Upload_Dir; use WDEV_Logger; use WP; class Png2Jpg_Controller extends Controller { const GLOBAL_STATS_OPTION_ID = 'wp-smush-png2jpg-global-stats'; const REWRITE_RULES_FLUSHED_OPTION = 'wp-smush-png2jpg-rewrite-rules-flushed'; const PNG2JPG_OPTIMIZATION_ORDER = 0; /** * @var WDEV_Logger */ private $logger; /** * @var Global_Stats */ private $global_stats; /** * @var Media_Item_Cache */ private $media_item_cache; /** * @var Png2Jpg_Helper */ private $helper; /** * Static instance * * @var self */ private static $instance; /** * @var File_System */ private $fs; /** * @var Settings */ private $settings; public static function get_instance() { if ( empty( self::$instance ) ) { self::$instance = new self(); } return self::$instance; } private function __construct() { $this->logger = Helper::logger()->png2jpg(); $this->global_stats = Global_Stats::get(); $this->media_item_cache = Media_Item_Cache::get_instance(); $this->helper = new Png2Jpg_Helper(); $this->fs = new File_System(); $this->settings = Settings::get_instance(); $this->register_filter( 'wp_smush_optimizations', array( $this, 'add_png2jpg_optimization', ), self::PNG2JPG_OPTIMIZATION_ORDER, 2 ); $this->register_filter( 'wp_smush_global_optimization_stats', array( $this, 'add_png2jpg_global_stats' ) ); $this->register_action( 'wp_smush_settings_updated', array( $this, 'maybe_mark_global_stats_as_outdated', ), 10, 2 ); $this->register_filter( 'wp_smush_scan_library_slice_handle_attachment', array( $this, 'maybe_update_transparent_status_during_scan', ), 10, 2 ); $this->register_action( 'wp_smush_after_attachment_upload', array( $this, 'maybe_update_transparent_status_on_upload', ) ); $this->register_action( 'wp_smush_before_smush_attempt', array( $this, 'maybe_update_transparent_status_before_optimization', ) ); if ( ! $this->settings->is_png2jpg_module_active() ) { return; } $this->register_action( 'init', array( $this, 'add_fallback_png_rewrite_rules' ) ); $this->register_action( 'wp', array( $this, 'serve_fallback_png' ) ); } public function add_fallback_png_rewrite_rules() { /** * @var $wp WP */ global $wp; $wp->add_query_var( 'smush_load_fallback_png' ); $upload_dir = new Upload_Dir(); $upload_rel_path = ltrim( $upload_dir->get_upload_rel_path(), '/' ); $this->logger->info( "Added rewrite rule [$upload_rel_path/(.*\.(?:png))$] so fallback PNGs can be served" ); add_rewrite_rule( "$upload_rel_path/(.*\.(?:png))$", 'index.php?smush_load_fallback_png=$matches[1]', 'top' ); $this->maybe_flush_rewrite_rules(); } public function serve_fallback_png() { $png_relative_path = get_query_var( 'smush_load_fallback_png' ); if ( ! $png_relative_path ) { return; } $this->logger->info( 'Attempting to serve a fallback PNG.' ); if ( headers_sent() ) { $this->logger->info( 'Attempted to serve a fallback PNG but headers have already been sent.' ); return; } $fallback_jpg_path = $this->get_fallback_jpg_path( $png_relative_path ); if ( ! $fallback_jpg_path ) { $this->logger->info( 'Attempted to serve a fallback PNG but no JPG was found for fallback.' ); return; } $extension = pathinfo( $fallback_jpg_path, PATHINFO_EXTENSION ); $mime_type = $extension === 'png' ? 'image/png' : 'image/jpeg'; status_header( 200 ); header( "Content-Type: $mime_type" ); readfile( $fallback_jpg_path ); exit; } public function get_fallback_jpg_path( $png_relative_path ) { global $wpdb; $wild = '%'; $png_relative_path = ltrim( $png_relative_path, '/' ); $path_like = $wild . $wpdb->esc_like( $png_relative_path ) . $wild; $row = $wpdb->get_row( $wpdb->prepare( "SELECT post_id, meta_key FROM {$wpdb->postmeta} WHERE meta_value LIKE %s LIMIT 1", $path_like ) ); if ( empty( $row ) ) { return false; } $media_item = Media_Item_Cache::get_instance()->get( $row->post_id ); if ( ! $media_item->is_image() ) { return false; } $optimization = new Png2Jpg_Optimization( $media_item ); $converted_png_files = $optimization->get_converted_png_files(); $size_key = array_search( $png_relative_path, $converted_png_files ); if ( ! empty( $size_key ) && $media_item->has_size( $size_key ) ) { $file_path = $media_item->get_size( $size_key )->get_file_path(); } else { $file_path = $media_item->get_main_size()->get_file_path(); } if ( ! $this->fs->file_exists( $file_path ) ) { return false; } return $file_path; } /** * @param $optimizations array * @param $media_item Media_Item * * @return array */ public function add_png2jpg_optimization( $optimizations, $media_item ) { $optimization = new Png2Jpg_Optimization( $media_item ); $optimizations[ $optimization->get_key() ] = $optimization; return $optimizations; } private function maybe_flush_rewrite_rules() { $flushed = get_option( self::REWRITE_RULES_FLUSHED_OPTION, false ); if ( WP_SMUSH_VERSION !== $flushed ) { $this->logger->info( "Flushing rewrite rules so fallback PNGs can be served" ); flush_rewrite_rules(); update_option( self::REWRITE_RULES_FLUSHED_OPTION, WP_SMUSH_VERSION ); } } public function add_png2jpg_global_stats( $stats ) { $stats[ Png2Jpg_Optimization::KEY ] = new Media_Item_Optimization_Global_Stats_Persistable( self::GLOBAL_STATS_OPTION_ID ); return $stats; } public function maybe_mark_global_stats_as_outdated( $old_settings, $settings ) { $png_to_jpg_old = ! empty( $old_settings['png_to_jpg'] ); $png_to_jpg_new = ! empty( $settings['png_to_jpg'] ); if ( $png_to_jpg_old !== $png_to_jpg_new ) { $this->global_stats->mark_as_outdated(); } } public function maybe_update_transparent_status_during_scan( $slice_data, $attachment_id ) { $this->maybe_update_transparent_status( $attachment_id ); return $slice_data; } public function maybe_update_transparent_status_on_upload( $attachment_id ) { $this->maybe_update_transparent_status( $attachment_id ); } /** * TODO: add test * * @param $attachment_id * * @return void */ public function maybe_update_transparent_status_before_optimization( $attachment_id ) { $this->maybe_update_transparent_status( $attachment_id ); } private function maybe_update_transparent_status( $attachment_id ) { // We are checking the status of the resize module here because the resize module destroys transparency information. $is_resize_module_active = $this->settings->is_resize_module_active(); $is_png2jpg_module_active = $this->settings->is_png2jpg_module_active(); $transparency_check_required = $is_png2jpg_module_active || $is_resize_module_active; if ( ! $transparency_check_required ) { return; } $media_item = $this->media_item_cache->get( $attachment_id ); if ( ! $media_item->is_valid() ) { $this->logger->error( 'Tried to check transparent value but encountered a problem with the media item' ); return; } if ( apply_filters( 'wp_smush_skip_image_transparency_check', false, $attachment_id ) ) { // The image is explicitly excluded from the transparency check return; } if ( ! $media_item->is_png() ) { // The media item is not even a png so no need to check. return; } if ( $media_item->transparent_meta_exists() ) { // Already checked, no need to check again. return; } $this->logger->log( 'Setting transparent meta value' ); $full_size = $media_item->get_full_or_scaled_size(); $is_transparent = $this->helper->is_transparent( $full_size->get_file_path(), $full_size->get_width(), $full_size->get_height() ); $set_transparent = $media_item->set_transparent( $is_transparent ); if ( $set_transparent ) { $media_item->save(); } } }