| @@ -1,29 +1,44 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | -namespace ImageOptimizer\Modules\Optimization\Classes; | |
| 3 | +namespace ImageOptimization\Modules\Optimization\Classes; | |
| 4 | 4 | |
| 5 | -use ImageOptimizer\Classes\File_Utils; | |
| 6 | -use ImageOptimizer\Classes\Image\{ | |
| 5 | +use ImageOptimization\Classes\File_System\{ | |
| 6 | + Exceptions\File_System_Operation_Error, | |
| 7 | + File_System, | |
| 8 | +}; | |
| 9 | +use ImageOptimization\Classes\File_Utils; | |
| 10 | +use ImageOptimization\Classes\Image\{ | |
| 11 | + Exceptions\Image_Backup_Creation_Error, | |
| 7 | 12 | Exceptions\Invalid_Image_Exception, |
| 8 | 13 | Image, |
| 9 | 14 | Image_Backup, |
| 15 | + Image_Conversion, | |
| 16 | + Image_DB_Update, | |
| 17 | + Image_Dimensions, | |
| 10 | 18 | Image_Meta, |
| 11 | 19 | Image_Status, |
| 12 | 20 | WP_Image_Meta |
| 13 | 21 | }; |
| 14 | -use ImageOptimizer\Classes\Utils; | |
| 15 | -use ImageOptimizer\Modules\Oauth\Components\Connect; | |
| 16 | -use ImageOptimizer\Modules\Optimization\Classes\Exceptions\Image_Optimization_Error; | |
| 17 | -use ImageOptimizer\Modules\Settings\Classes\Settings; | |
| 22 | +use ImageOptimization\Classes\Logger; | |
| 23 | +use ImageOptimization\Classes\Utils; | |
| 24 | +use ImageOptimization\Classes\Exceptions\Quota_Exceeded_Error; | |
| 25 | +use ImageOptimization\Modules\Optimization\Classes\{ | |
| 26 | + Exceptions\Image_File_Already_Exists_Error, | |
| 27 | + Exceptions\Image_Optimization_Error, | |
| 28 | + Exceptions\Bulk_Token_Expired_Error, | |
| 29 | + Exceptions\Image_Already_Optimized_Error, | |
| 30 | +}; | |
| 31 | +use ImageOptimization\Modules\Connect\Classes\Exceptions\Connection_Error; | |
| 32 | +use ImageOptimization\Modules\Settings\Classes\Settings; | |
| 33 | +use Throwable; | |
| 18 | 34 | |
| 35 | +use ImageOptimization\Plugin; | |
| 36 | + | |
| 19 | 37 | if ( ! defined( 'ABSPATH' ) ) { |
| 20 | 38 | exit; // Exit if accessed directly. |
| 21 | 39 | } |
| 22 | 40 | |
| 23 | -require_once ABSPATH . 'wp-admin/includes/file.php'; | |
| 24 | -WP_Filesystem(); | |
| 25 | - | |
| 26 | 41 | /** |
| 27 | 42 | * The class is responsible for the optimization logic itself. It gets an image file, runs |
| 28 | 43 | * backup process if needed, sends a file to the service, stores the result and updates image meta. |
| 29 | 44 | * |
| @@ -29,9 +44,9 @@ | ||
| 29 | 44 | * |
| 30 | 45 | * This class is used by manual, bulk and on-upload optimization flows. |
| 31 | 46 | */ |
| 32 | 47 | class Optimize_Image { |
| 33 | - private const IMAGE_OPTIMIZE_ENDPOINT = 'image/optimize'; | |
| 48 | + public const IMAGE_OPTIMIZE_ENDPOINT = 'image/optimize'; | |
| 34 | 49 | |
| 35 | 50 | protected ?Image $image; |
| 36 | 51 | protected WP_Image_Meta $wp_meta; |
| 37 | 52 | protected string $initiator; |
| @@ -37,17 +52,22 @@ | ||
| 37 | 52 | protected string $initiator; |
| 38 | 53 | protected ?string $bulk_token; |
| 39 | 54 | private string $current_image_path; |
| 40 | 55 | private string $current_image_size; |
| 41 | - private bool $convert_to_webp; | |
| 56 | + private bool $keep_backups; | |
| 57 | + private array $current_size_duplicates; | |
| 58 | + protected Image_Conversion $image_conversion; | |
| 59 | + private bool $is_reoptimize; | |
| 42 | 60 | |
| 43 | 61 | /** |
| 44 | - * @throws Image_Optimization_Error | |
| 62 | + * @throws Quota_Exceeded_Error|Connection_Error|Bulk_Token_Expired_Error|Image_File_Already_Exists_Error|Image_Optimization_Error | |
| 45 | 63 | */ |
| 46 | 64 | public function optimize(): void { |
| 47 | 65 | $sizes_enabled = Settings::get( Settings::CUSTOM_SIZES_OPTION_NAME ); |
| 48 | 66 | $sizes_exist = $this->wp_meta->get_size_keys(); |
| 49 | 67 | |
| 68 | + Logger::debug( "Start optimization of {$this->image->get_id()}" ); | |
| 69 | + | |
| 50 | 70 | foreach ( $sizes_exist as $size_exist ) { |
| 51 | 71 | // If some image sizes optimization is disabled in settings, we check if the current one is still enabled |
| 52 | 72 | if ( |
| 53 | 73 | 'all' !== $sizes_enabled && |
| @@ -56,59 +76,82 @@ | ||
| 56 | 76 | ) { |
| 57 | 77 | continue; |
| 58 | 78 | } |
| 59 | 79 | |
| 80 | + // Elementor editor generates thumbnails we don't need to optimize. | |
| 81 | + if ( str_starts_with( $size_exist, 'elementor_' ) ) { | |
| 82 | + continue; | |
| 83 | + } | |
| 84 | + | |
| 60 | 85 | $image_meta = new Image_Meta( $this->image->get_id() ); |
| 61 | 86 | |
| 62 | 87 | // If the current size was already optimized -- ignore it. |
| 63 | - if ( in_array( $size_exist, $image_meta->get_optimized_sizes(), true ) ) { | |
| 88 | + if ( ! $this->is_reoptimize && in_array( $size_exist, $image_meta->get_optimized_sizes(), true ) ) { | |
| 89 | + Logger::debug( "Size `$size_exist` is already optimized" ); | |
| 90 | + | |
| 64 | 91 | continue; |
| 65 | 92 | } |
| 66 | 93 | |
| 67 | 94 | if ( ! file_exists( $this->image->get_file_path( $size_exist ) ) ) { |
| 68 | - throw new Image_Optimization_Error( esc_html__( 'File is missing. Verify the upload', 'image-optimizer' ) ); | |
| 95 | + Logger::debug( "Can't access file for size `$size_exist`" ); | |
| 96 | + | |
| 97 | + continue; | |
| 69 | 98 | } |
| 70 | 99 | |
| 71 | 100 | $this->current_image_size = $size_exist; |
| 101 | + $this->current_size_duplicates = $this->wp_meta->get_size_duplicates( $size_exist ); | |
| 72 | 102 | $this->current_image_path = $this->image->get_file_path( $size_exist ); |
| 73 | 103 | |
| 74 | 104 | $this->optimize_current_size(); |
| 75 | 105 | |
| 76 | 106 | $this->current_image_size = ''; |
| 107 | + $this->current_size_duplicates = []; | |
| 77 | 108 | $this->current_image_path = ''; |
| 78 | 109 | } |
| 79 | 110 | |
| 80 | 111 | $this->mark_as_optimized(); |
| 112 | + | |
| 113 | + if ( ! $this->keep_backups ) { | |
| 114 | + Image_Backup::remove( $this->image->get_id() ); | |
| 115 | + } | |
| 116 | + | |
| 117 | + Logger::debug( "End optimization of {$this->image->get_id()}" ); | |
| 81 | 118 | } |
| 82 | 119 | |
| 83 | - /** | |
| 84 | - * @throws Image_Optimization_Error | |
| 85 | - */ | |
| 86 | 120 | private function optimize_current_size(): void { |
| 87 | - $response = $this->send_file(); | |
| 121 | + try { | |
| 122 | + $original_path = $this->current_image_path; | |
| 123 | + $response = $this->send_file(); | |
| 88 | 124 | |
| 89 | - if ( is_wp_error( $response ) ) { | |
| 90 | - throw new Image_Optimization_Error( $response->get_error_message() ); | |
| 91 | - } | |
| 125 | + $optimized_size = (int) $response->optimizedSize; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase | |
| 126 | + $optimized_image_binary = base64_decode( $response->image, true ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode | |
| 92 | 127 | |
| 93 | - $original_size = (int) $response->originalSize; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase | |
| 94 | - $optimized_size = (int) $response->optimizedSize; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase | |
| 95 | - $optimized_image_binary = base64_decode( $response->image, true ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_decode | |
| 96 | - | |
| 97 | - // Sometimes the BE returns images bigger than original ones. In that case, we don't want to replace the original. | |
| 98 | - if ( $original_size > $optimized_size ) { | |
| 99 | 128 | $this->replace_image_file( $optimized_image_binary ); |
| 100 | 129 | $this->update_attachment_meta( $optimized_size ); |
| 101 | - } else { | |
| 102 | - $this->update_attachment_meta( $original_size ); | |
| 130 | + | |
| 131 | + if ( $original_path !== $this->current_image_path ) { | |
| 132 | + $this->update_posts( $original_path, $this->current_image_path ); | |
| 133 | + } | |
| 134 | + | |
| 135 | + // This should only be updated after meta | |
| 136 | + $this->update_attachment_post(); | |
| 137 | + } catch ( Image_Already_Optimized_Error $iao ) { | |
| 138 | + // If we can't optimize it further, just update the meta | |
| 139 | + $original_size = $this->wp_meta->get_file_size( $this->current_image_size ) | |
| 140 | + ?? File_System::size( $this->image->get_file_path( $this->current_image_size ) ); | |
| 141 | + | |
| 142 | + $this->update_attachment_meta( $original_size, true ); | |
| 143 | + $this->update_attachment_post( true ); | |
| 144 | + } catch ( Bulk_Token_Expired_Error | Quota_Exceeded_Error | Connection_Error | Image_File_Already_Exists_Error $e ) { | |
| 145 | + throw $e; | |
| 146 | + } catch ( Throwable $t ) { | |
| 147 | + // In case of anything else | |
| 148 | + throw new Image_Optimization_Error( esc_html( $t->getMessage() ) ); | |
| 103 | 149 | } |
| 104 | - | |
| 105 | - // This should only be updated after meta | |
| 106 | - $this->update_attachment_post(); | |
| 107 | 150 | } |
| 108 | 151 | |
| 109 | 152 | private function send_file() { |
| 110 | - $connect_status = Connect::check_connect_status(); | |
| 153 | + $connect_status = Plugin::instance()->modules_manager->get_modules( 'connect-manager' )->connect_instance->get_connect_status(); | |
| 111 | 154 | $headers = [ |
| 112 | 155 | 'access_token' => $connect_status->access_token ?? '', |
| 113 | 156 | ]; |
| 114 | 157 | |
| @@ -117,9 +160,9 @@ | ||
| 117 | 160 | } |
| 118 | 161 | |
| 119 | 162 | $optimization_options = [ |
| 120 | 163 | 'compression_level' => Settings::get( Settings::COMPRESSION_LEVEL_OPTION_NAME ), |
| 121 | - 'convert_to_webp' => $this->convert_to_webp, | |
| 164 | + 'convert_to_format' => $this->image_conversion->get_current_conversion_option(), | |
| 122 | 165 | 'strip_exif' => Settings::get( Settings::STRIP_EXIF_METADATA_OPTION_NAME ), |
| 123 | 166 | ]; |
| 124 | 167 | |
| 125 | 168 | if ( Settings::get( Settings::RESIZE_LARGER_IMAGES_OPTION_NAME ) ) { |
| @@ -125,14 +168,18 @@ | ||
| 125 | 168 | if ( Settings::get( Settings::RESIZE_LARGER_IMAGES_OPTION_NAME ) ) { |
| 126 | 169 | $optimization_options['resize'] = Settings::get( Settings::RESIZE_LARGER_IMAGES_SIZE_OPTION_NAME ); |
| 127 | 170 | } |
| 128 | 171 | |
| 129 | - return Utils::get_api_client()->make_request( | |
| 172 | + $image_key = wp_generate_password( 15, false ); | |
| 173 | + | |
| 174 | + $response = Utils::get_api_client()->make_request( | |
| 130 | 175 | 'POST', |
| 131 | 176 | self::IMAGE_OPTIMIZE_ENDPOINT, |
| 132 | 177 | [ |
| 133 | 178 | 'initiator' => $this->initiator, |
| 134 | 179 | 'image_url' => $this->image->get_url( $this->current_image_size ), |
| 180 | + 'image_key' => $image_key, | |
| 181 | + 'checksum' => md5_file( $this->current_image_path ), | |
| 135 | 182 | 'attachment_id' => $this->image->get_id(), |
| 136 | 183 | 'attachment_parent_id' => Image::SIZE_FULL === $this->current_image_size ? 0 : $this->image->get_id(), |
| 137 | 184 | 'image_optimization_settings' => base64_encode( wp_json_encode( $optimization_options ) ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode |
| 138 | 185 | ], |
| @@ -139,13 +186,34 @@ | ||
| 139 | 186 | $headers, |
| 140 | 187 | $this->current_image_path, |
| 141 | 188 | 'image' |
| 142 | 189 | ); |
| 190 | + | |
| 191 | + if ( isset( $response->stats ) ) { | |
| 192 | + Plugin::instance()->modules_manager->get_modules( 'connect-manager' )->connect_instance->update_usage_data( $response->stats ); | |
| 193 | + } | |
| 194 | + | |
| 195 | + if ( ! isset( $response->imageKey ) || $image_key !== $response->imageKey ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase | |
| 196 | + Logger::error( "Image key must be $image_key, instead got $response->imageKey" ); | |
| 197 | + | |
| 198 | + throw new Image_Optimization_Error( esc_html__( 'Service response is incorrect', 'image-optimization' ) ); | |
| 199 | + } | |
| 200 | + | |
| 201 | + $received_file_hash = md5( base64_decode( $response->image, true ) ); | |
| 202 | + | |
| 203 | + if ( ! isset( $response->checksum ) || $received_file_hash !== $response->checksum ) { | |
| 204 | + Logger::error( "Image key must be $response->checksum, instead calculated $received_file_hash" ); | |
| 205 | + | |
| 206 | + throw new Image_Optimization_Error( esc_html__( 'Service response is incorrect', 'image-optimization' ) ); | |
| 207 | + } | |
| 208 | + | |
| 209 | + return $response; | |
| 143 | 210 | } |
| 144 | 211 | |
| 212 | + /** | |
| 213 | + * @throws File_System_Operation_Error|Image_Backup_Creation_Error|Image_File_Already_Exists_Error | |
| 214 | + */ | |
| 145 | 215 | private function replace_image_file( string $file_data ): void { |
| 146 | - global $wp_filesystem; | |
| 147 | - | |
| 148 | 216 | $path = $this->current_image_path; |
| 149 | 217 | |
| 150 | 218 | // If we have backups disabled, we want to make sure we can download and save new file before we |
| 151 | 219 | // remove an existing one. |
| @@ -150,23 +218,40 @@ | ||
| 150 | 218 | // If we have backups disabled, we want to make sure we can download and save new file before we |
| 151 | 219 | // remove an existing one. |
| 152 | 220 | $tmp_path = File_Utils::replace_extension( $path, 'tmp' ); |
| 153 | 221 | |
| 154 | - $wp_filesystem->put_contents( $tmp_path, $file_data ); | |
| 222 | + File_System::put_contents( $tmp_path, $file_data ); | |
| 155 | 223 | |
| 156 | - // The original file doesn't exist after any of these operations. | |
| 157 | - if ( Settings::get( Settings::BACKUP_ORIGINAL_IMAGES_OPTION_NAME ) ) { | |
| 224 | + if ( $this->image_conversion->is_enabled() ) { | |
| 225 | + $converted_path = File_Utils::replace_extension( $tmp_path, $this->image_conversion->get_current_file_extension() ); | |
| 226 | + $original_is_already_converted = strtolower( $path ) === strtolower( $converted_path ); | |
| 227 | + | |
| 228 | + if ( ! $original_is_already_converted && File_System::exists( $converted_path ) ) { | |
| 229 | + throw new Image_File_Already_Exists_Error(); | |
| 230 | + } | |
| 231 | + | |
| 232 | + // We want to keep both original as a fallback and optimized webp to prevent 404s | |
| 233 | + if ( ! $original_is_already_converted ) { | |
| 234 | + $this->keep_backups = true; | |
| 235 | + | |
| 236 | + ( new Image_Meta( $this->image->get_id() ) ) | |
| 237 | + ->set_image_backup_path( $this->current_image_size, $this->current_image_path ) | |
| 238 | + ->save(); | |
| 239 | + } | |
| 240 | + | |
| 241 | + if ( $original_is_already_converted ) { | |
| 242 | + Image_Backup::create( $this->image->get_id(), $this->current_image_size, $this->current_image_path ); | |
| 243 | + } | |
| 244 | + | |
| 245 | + File_System::move( $tmp_path, $converted_path, true ); | |
| 246 | + | |
| 247 | + $path = $converted_path; | |
| 248 | + } else { | |
| 158 | 249 | Image_Backup::create( $this->image->get_id(), $this->current_image_size, $this->current_image_path ); |
| 159 | - } else { | |
| 160 | - $wp_filesystem->delete( $path, false, 'f' ); | |
| 161 | - } | |
| 162 | 250 | |
| 163 | - if ( $this->convert_to_webp ) { | |
| 164 | - $path = File_Utils::replace_extension( $tmp_path, 'webp' ); | |
| 251 | + File_System::move( $tmp_path, $path, true ); | |
| 165 | 252 | } |
| 166 | 253 | |
| 167 | - $wp_filesystem->move( $tmp_path, $path, true ); | |
| 168 | - | |
| 169 | 254 | if ( Image::SIZE_FULL === $this->current_image_size ) { |
| 170 | 255 | // Drop WP caches |
| 171 | 256 | update_attached_file( $this->image->get_id(), $path ); |
| 172 | 257 | } |
| @@ -179,16 +264,20 @@ | ||
| 179 | 264 | * Updates attachment records in the `wp_posts` table. |
| 180 | 265 | * |
| 181 | 266 | * @return void |
| 182 | 267 | */ |
| 183 | - private function update_attachment_post() { | |
| 268 | + private function update_attachment_post( ?bool $is_fully_optimized = false ) { | |
| 184 | 269 | $update_query = []; |
| 185 | 270 | |
| 186 | - if ( $this->convert_to_webp ) { | |
| 271 | + if ( $this->image_conversion->is_enabled() && ! $is_fully_optimized ) { | |
| 187 | 272 | $attachment_object = $this->image->get_attachment_object(); |
| 188 | 273 | |
| 189 | - $update_query['guid'] = File_Utils::replace_extension( $attachment_object->guid, 'webp' ); | |
| 190 | - $update_query['post_mime_type'] = 'image/webp'; | |
| 274 | + $update_query['guid'] = File_Utils::replace_extension( | |
| 275 | + $attachment_object->guid, | |
| 276 | + $this->image_conversion->get_current_file_extension() | |
| 277 | + ); | |
| 278 | + | |
| 279 | + $update_query['post_mime_type'] = $this->image_conversion->get_current_mime_type(); | |
| 191 | 280 | } |
| 192 | 281 | |
| 193 | 282 | $update_query['post_modified'] = current_time( 'mysql' ); |
| 194 | 283 | $update_query['post_modified_gmt'] = current_time( 'mysql', true ); |
| @@ -199,30 +288,34 @@ | ||
| 199 | 288 | /** |
| 200 | 289 | * Updates attachment records in the `wp_postmeta` table. |
| 201 | 290 | * |
| 202 | 291 | * @param int $optimized_size |
| 292 | + * @param bool|null $is_fully_optimized | |
| 203 | 293 | * |
| 204 | 294 | * @return void |
| 205 | 295 | */ |
| 206 | - private function update_attachment_meta( int $optimized_size ) { | |
| 296 | + private function update_attachment_meta( int $optimized_size, ?bool $is_fully_optimized = false ) { | |
| 207 | 297 | $meta = new Image_Meta( $this->image->get_id() ); |
| 298 | + $dimensions = Image_Dimensions::get_by_path( $this->current_image_path ); | |
| 208 | 299 | |
| 209 | - list($width, $height) = getimagesize( $this->current_image_path ); | |
| 300 | + $sizes_to_update = [ $this->current_image_size, ...$this->current_size_duplicates ]; | |
| 210 | 301 | |
| 211 | - $meta | |
| 212 | - ->set_compression_level( Settings::get( Settings::COMPRESSION_LEVEL_OPTION_NAME ) ) | |
| 213 | - ->add_optimized_size( $this->current_image_size ) | |
| 214 | - ->add_original_data( $this->current_image_size, $this->wp_meta->get_size_data( $this->current_image_size ) ); | |
| 302 | + foreach ( $sizes_to_update as $size ) { | |
| 303 | + $meta | |
| 304 | + ->set_compression_level( Settings::get( Settings::COMPRESSION_LEVEL_OPTION_NAME ) ) | |
| 305 | + ->add_optimized_size( $size ) | |
| 306 | + ->add_original_data( $size, $this->wp_meta->get_size_data( $size ) ); | |
| 215 | 307 | |
| 216 | - $this->wp_meta | |
| 217 | - ->set_width( $this->current_image_size, $width ) | |
| 218 | - ->set_height( $this->current_image_size, $height ) | |
| 219 | - ->set_file_size( $this->current_image_size, $optimized_size ); | |
| 308 | + $this->wp_meta | |
| 309 | + ->set_width( $size, $dimensions->width ) | |
| 310 | + ->set_height( $size, $dimensions->height ) | |
| 311 | + ->set_file_size( $size, $optimized_size ); | |
| 220 | 312 | |
| 221 | - if ( $this->convert_to_webp ) { | |
| 222 | - $this->wp_meta | |
| 223 | - ->set_file_path( $this->current_image_size, $this->current_image_path ) | |
| 224 | - ->set_mime_type( $this->current_image_size, 'image/webp' ); | |
| 313 | + if ( $this->image_conversion->is_enabled() && ! $is_fully_optimized ) { | |
| 314 | + $this->wp_meta | |
| 315 | + ->set_file_path( $size, $this->current_image_path ) | |
| 316 | + ->set_mime_type( $size, $this->image_conversion->get_current_mime_type() ); | |
| 317 | + } | |
| 225 | 318 | } |
| 226 | 319 | |
| 227 | 320 | $meta->save(); |
| 228 | 321 | $this->wp_meta->save(); |
| @@ -228,8 +321,24 @@ | ||
| 228 | 321 | $this->wp_meta->save(); |
| 229 | 322 | } |
| 230 | 323 | |
| 231 | 324 | /** |
| 325 | + * If we change an image extension, we should walk through the wp_posts table and update all the | |
| 326 | + * hardcoded image links to prevent 404s. | |
| 327 | + * | |
| 328 | + * @param string $old_path Previous image path | |
| 329 | + * @param string $new_path Current image path | |
| 330 | + * | |
| 331 | + * @return void | |
| 332 | + */ | |
| 333 | + private function update_posts( string $old_path, string $new_path ) { | |
| 334 | + Image_DB_Update::update_posts_table_urls( | |
| 335 | + File_Utils::get_url_from_path( $old_path ), | |
| 336 | + File_Utils::get_url_from_path( $new_path ) | |
| 337 | + ); | |
| 338 | + } | |
| 339 | + | |
| 340 | + /** | |
| 232 | 341 | * Changes image status after all image sizes were optimized. |
| 233 | 342 | * |
| 234 | 343 | * @return void |
| 235 | 344 | */ |
| @@ -235,8 +344,9 @@ | ||
| 235 | 344 | */ |
| 236 | 345 | private function mark_as_optimized() { |
| 237 | 346 | ( new Image_Meta( $this->image->get_id() ) ) |
| 238 | 347 | ->set_status( Image_Status::OPTIMIZED ) |
| 348 | + ->set_error_type( null ) | |
| 239 | 349 | ->save(); |
| 240 | 350 | } |
| 241 | 351 | |
| 242 | 352 | /** |
| @@ -241,12 +351,14 @@ | ||
| 241 | 351 | |
| 242 | 352 | /** |
| 243 | 353 | * @throws Invalid_Image_Exception |
| 244 | 354 | */ |
| 245 | - public function __construct( int $image_id, string $initiator, ?string $bulk_token = null ) { | |
| 355 | + public function __construct( int $image_id, string $initiator, ?string $bulk_token = null, ?bool $is_reoptimize = false ) { | |
| 246 | 356 | $this->image = new Image( $image_id ); |
| 247 | 357 | $this->wp_meta = new WP_Image_Meta( $image_id, $this->image ); |
| 248 | 358 | $this->initiator = $initiator; |
| 249 | 359 | $this->bulk_token = $bulk_token; |
| 250 | - $this->convert_to_webp = Settings::get( Settings::CONVERT_TO_WEBP_OPTION_NAME ); | |
| 360 | + $this->is_reoptimize = $is_reoptimize; | |
| 361 | + $this->image_conversion = new Image_Conversion(); | |
| 362 | + $this->keep_backups = Settings::get( Settings::BACKUP_ORIGINAL_IMAGES_OPTION_NAME ); | |
| 251 | 363 | } |
| 252 | 364 | } |