PluginProbe
Image Optimizer – Compress Images and Convert to WebP or AVIF / 1.7.7
Image Optimizer – Compress Images and Convert to WebP or AVIF v1.7.7
1.7.7 1.7.6 1.7.5 1.7.4 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.2.0 1.2.1 1.3.0 1.4.0 1.4.1 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 All 33 releases
← All changes | modules/optimization/classes/optimize-image.php +30 -44 1.5.01.7.7 View file →
@@ -13,15 +13,16 @@
13 13 Image,
14 14 Image_Backup,
15 15 Image_Conversion,
16 16 Image_DB_Update,
17 + Image_Dimensions,
17 18 Image_Meta,
18 19 Image_Status,
19 - WP_Image_Meta};
20 + WP_Image_Meta
21 +};
20 22 use ImageOptimization\Classes\Logger;
21 23 use ImageOptimization\Classes\Utils;
22 24 use ImageOptimization\Classes\Exceptions\Quota_Exceeded_Error;
23 -use ImageOptimization\Modules\Oauth\Components\Connect;
24 25 use ImageOptimization\Modules\Optimization\Classes\{
25 26 Exceptions\Image_File_Already_Exists_Error,
26 27 Exceptions\Image_Optimization_Error,
27 28 Exceptions\Bulk_Token_Expired_Error,
@@ -26,8 +27,9 @@
26 27 Exceptions\Image_Optimization_Error,
27 28 Exceptions\Bulk_Token_Expired_Error,
28 29 Exceptions\Image_Already_Optimized_Error,
29 30 };
31 +use ImageOptimization\Modules\Connect\Classes\Exceptions\Connection_Error;
30 32 use ImageOptimization\Modules\Settings\Classes\Settings;
31 33 use Throwable;
32 34
33 35 use ImageOptimization\Plugin;
@@ -42,9 +44,9 @@
42 44 *
43 45 * This class is used by manual, bulk and on-upload optimization flows.
44 46 */
45 47 class Optimize_Image {
46 - private const IMAGE_OPTIMIZE_ENDPOINT = 'image/optimize';
48 + public const IMAGE_OPTIMIZE_ENDPOINT = 'image/optimize';
47 49
48 50 protected ?Image $image;
49 51 protected WP_Image_Meta $wp_meta;
50 52 protected string $initiator;
@@ -53,20 +55,18 @@
53 55 private string $current_image_size;
54 56 private bool $keep_backups;
55 57 private array $current_size_duplicates;
56 58 protected Image_Conversion $image_conversion;
59 + private bool $is_reoptimize;
57 60
58 61 /**
59 - * @throws Quota_Exceeded_Error|Bulk_Token_Expired_Error|Image_File_Already_Exists_Error|Image_Optimization_Error
62 + * @throws Quota_Exceeded_Error|Connection_Error|Bulk_Token_Expired_Error|Image_File_Already_Exists_Error|Image_Optimization_Error
60 63 */
61 64 public function optimize(): void {
62 65 $sizes_enabled = Settings::get( Settings::CUSTOM_SIZES_OPTION_NAME );
63 66 $sizes_exist = $this->wp_meta->get_size_keys();
64 67
65 - Logger::log(
66 - Logger::LEVEL_INFO,
67 - "Start optimization of {$this->image->get_id()}"
68 - );
68 + Logger::debug( "Start optimization of {$this->image->get_id()}" );
69 69
70 70 foreach ( $sizes_exist as $size_exist ) {
71 71 // If some image sizes optimization is disabled in settings, we check if the current one is still enabled
72 72 if (
@@ -84,24 +84,18 @@
84 84
85 85 $image_meta = new Image_Meta( $this->image->get_id() );
86 86
87 87 // If the current size was already optimized -- ignore it.
88 - if ( in_array( $size_exist, $image_meta->get_optimized_sizes(), true ) ) {
89 - Logger::log(
90 - Logger::LEVEL_INFO,
91 - "Size `$size_exist` is already optimized"
92 - );
88 + if ( ! $this->is_reoptimize && in_array( $size_exist, $image_meta->get_optimized_sizes(), true ) ) {
89 + Logger::debug( "Size `$size_exist` is already optimized" );
93 90
94 91 continue;
95 92 }
96 93
97 94 if ( ! file_exists( $this->image->get_file_path( $size_exist ) ) ) {
98 - Logger::log(
99 - Logger::LEVEL_ERROR,
100 - "Can't access file for size `$size_exist`"
101 - );
95 + Logger::debug( "Can't access file for size `$size_exist`" );
102 96
103 - throw new Image_Optimization_Error( esc_html__( 'File is missing. Verify the upload', 'image-optimization' ) );
97 + continue;
104 98 }
105 99
106 100 $this->current_image_size = $size_exist;
107 101 $this->current_size_duplicates = $this->wp_meta->get_size_duplicates( $size_exist );
@@ -119,12 +113,9 @@
119 113 if ( ! $this->keep_backups ) {
120 114 Image_Backup::remove( $this->image->get_id() );
121 115 }
122 116
123 - Logger::log(
124 - Logger::LEVEL_INFO,
125 - "End optimization of {$this->image->get_id()}"
126 - );
117 + Logger::debug( "End optimization of {$this->image->get_id()}" );
127 118 }
128 119
129 120 private function optimize_current_size(): void {
130 121 try {
@@ -143,19 +134,19 @@
143 134
144 135 // This should only be updated after meta
145 136 $this->update_attachment_post();
146 137 } catch ( Image_Already_Optimized_Error $iao ) {
147 - // If we can't optimize it further, just file update the meta
138 + // If we can't optimize it further, just update the meta
148 139 $original_size = $this->wp_meta->get_file_size( $this->current_image_size )
149 140 ?? File_System::size( $this->image->get_file_path( $this->current_image_size ) );
150 141
151 - $this->update_attachment_meta( $original_size );
152 - $this->update_attachment_post();
153 - } catch ( Bulk_Token_Expired_Error | Quota_Exceeded_Error | Image_File_Already_Exists_Error $e ) {
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 ) {
154 145 throw $e;
155 146 } catch ( Throwable $t ) {
156 147 // In case of anything else
157 - throw new Image_Optimization_Error( $t->getMessage() );
148 + throw new Image_Optimization_Error( esc_html( $t->getMessage() ) );
158 149 }
159 150 }
160 151
161 152 private function send_file() {
@@ -201,12 +192,9 @@
201 192 Plugin::instance()->modules_manager->get_modules( 'connect-manager' )->connect_instance->update_usage_data( $response->stats );
202 193 }
203 194
204 195 if ( ! isset( $response->imageKey ) || $image_key !== $response->imageKey ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
205 - Logger::log(
206 - Logger::LEVEL_ERROR,
207 - "Image key must be $image_key, instead got $response->imageKey"
208 - );
196 + Logger::error( "Image key must be $image_key, instead got $response->imageKey" );
209 197
210 198 throw new Image_Optimization_Error( esc_html__( 'Service response is incorrect', 'image-optimization' ) );
211 199 }
212 200
@@ -212,12 +200,9 @@
212 200
213 201 $received_file_hash = md5( base64_decode( $response->image, true ) );
214 202
215 203 if ( ! isset( $response->checksum ) || $received_file_hash !== $response->checksum ) {
216 - Logger::log(
217 - Logger::LEVEL_ERROR,
218 - "Image key must be $response->checksum, instead calculated $received_file_hash"
219 - );
204 + Logger::error( "Image key must be $response->checksum, instead calculated $received_file_hash" );
220 205
221 206 throw new Image_Optimization_Error( esc_html__( 'Service response is incorrect', 'image-optimization' ) );
222 207 }
223 208
@@ -279,12 +264,12 @@
279 264 * Updates attachment records in the `wp_posts` table.
280 265 *
281 266 * @return void
282 267 */
283 - private function update_attachment_post() {
268 + private function update_attachment_post( ?bool $is_fully_optimized = false ) {
284 269 $update_query = [];
285 270
286 - if ( $this->image_conversion->is_enabled() ) {
271 + if ( $this->image_conversion->is_enabled() && ! $is_fully_optimized ) {
287 272 $attachment_object = $this->image->get_attachment_object();
288 273
289 274 $update_query['guid'] = File_Utils::replace_extension(
290 275 $attachment_object->guid,
@@ -303,16 +288,16 @@
303 288 /**
304 289 * Updates attachment records in the `wp_postmeta` table.
305 290 *
306 291 * @param int $optimized_size
292 + * @param bool|null $is_fully_optimized
307 293 *
308 294 * @return void
309 295 */
310 - private function update_attachment_meta( int $optimized_size ) {
296 + private function update_attachment_meta( int $optimized_size, ?bool $is_fully_optimized = false ) {
311 297 $meta = new Image_Meta( $this->image->get_id() );
298 + $dimensions = Image_Dimensions::get_by_path( $this->current_image_path );
312 299
313 - list($width, $height) = getimagesize( $this->current_image_path );
314 -
315 300 $sizes_to_update = [ $this->current_image_size, ...$this->current_size_duplicates ];
316 301
317 302 foreach ( $sizes_to_update as $size ) {
318 303 $meta
@@ -320,13 +305,13 @@
320 305 ->add_optimized_size( $size )
321 306 ->add_original_data( $size, $this->wp_meta->get_size_data( $size ) );
322 307
323 308 $this->wp_meta
324 - ->set_width( $size, $width )
325 - ->set_height( $size, $height )
309 + ->set_width( $size, $dimensions->width )
310 + ->set_height( $size, $dimensions->height )
326 311 ->set_file_size( $size, $optimized_size );
327 312
328 - if ( $this->image_conversion->is_enabled() ) {
313 + if ( $this->image_conversion->is_enabled() && ! $is_fully_optimized ) {
329 314 $this->wp_meta
330 315 ->set_file_path( $size, $this->current_image_path )
331 316 ->set_mime_type( $size, $this->image_conversion->get_current_mime_type() );
332 317 }
@@ -366,13 +351,14 @@
366 351
367 352 /**
368 353 * @throws Invalid_Image_Exception
369 354 */
370 - 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 ) {
371 356 $this->image = new Image( $image_id );
372 357 $this->wp_meta = new WP_Image_Meta( $image_id, $this->image );
373 358 $this->initiator = $initiator;
374 359 $this->bulk_token = $bulk_token;
360 + $this->is_reoptimize = $is_reoptimize;
375 361 $this->image_conversion = new Image_Conversion();
376 362 $this->keep_backups = Settings::get( Settings::BACKUP_ORIGINAL_IMAGES_OPTION_NAME );
377 363 }
378 364 }