PluginProbe
Image Optimizer – Compress Images and Convert to WebP or AVIF / trunk
Image Optimizer – Compress Images and Convert to WebP or AVIF vtrunk
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/stats/classes/optimization-stats.php +91 -14 1.5.1 → trunk View file →
@@ -5,8 +5,9 @@
5 5 use ImageOptimization\Classes\Image\{
6 6 Image,
7 7 Image_Meta,
8 8 Image_Query_Builder,
9 + Image_Status,
9 10 WP_Image_Meta,
10 11 Exceptions\Invalid_Image_Exception
11 12 };
12 13 use ImageOptimization\Classes\Async_Operation\{
@@ -29,9 +30,9 @@
29 30 exit; // Exit if accessed directly.
30 31 }
31 32
32 33 class Optimization_Stats {
33 - const PAGING_SIZE = 25000;
34 + const PAGING_SIZE = 2000;
34 35 const STATS_CALCULATION_DELAY = 60 * 15;
35 36
36 37 /**
37 38 * Returns image stats.
@@ -62,13 +63,11 @@
62 63 // Otherwise, recalculate the stats.
63 64 $output = self::get_image_stats_chunk( 1, $image_id );
64 65 $pages_count = $output['pages'];
65 66
66 - if ( 1 === $pages_count ) {
67 + if ( $pages_count <= 1 ) {
67 68 unset( $output['pages'] );
68 69
69 - self::set_stored_stats( $output );
70 -
71 70 return $output;
72 71 }
73 72
74 73 if ( $pages_count > 1 && Async_Operation::OPERATION_STATUS_NOT_STARTED === self::get_stats_calculation_status() ) {
@@ -119,33 +118,109 @@
119 118
120 119 foreach ( $query->posts as $attachment_id ) {
121 120 try {
122 121 Validate_Image::is_valid( $attachment_id );
122 +
123 + $image = new Image( $attachment_id );
123 124 $wp_meta = new WP_Image_Meta( $attachment_id );
124 125 } catch ( Invalid_Image_Exception | Image_Validation_Error $ie ) {
125 - Logger::log( Logger::LEVEL_ERROR, $ie->getMessage() );
126 -
127 126 continue;
128 127 }
129 128
130 129 $meta = new Image_Meta( $attachment_id );
131 - $image_sizes = $wp_meta->get_size_keys();
130 + $image_sizes = self::filter_only_enabled_sizes( $wp_meta->get_size_keys() );
132 131
133 - $current_sizes = self::filter_only_enabled_sizes( $image_sizes );
134 - $optimized_sizes = self::filter_only_enabled_sizes( $meta->get_optimized_sizes() );
132 + foreach ( $image_sizes as $image_size ) {
133 + if ( ! $image->file_exists( $image_size ) ) {
134 + continue;
135 + }
135 136
136 - $output['total_image_count'] += count( $current_sizes );
137 - $output['optimized_image_count'] += count( $optimized_sizes );
137 + $output['total_image_count']++;
138 138
139 - foreach ( $image_sizes as $image_size ) {
140 139 $output['current_image_size'] += self::calculate_current_image_file_size( $attachment_id, $wp_meta, $image_size );
141 140 $output['initial_image_size'] += self::calculate_initial_image_file_size( $attachment_id, $meta, $wp_meta, $image_size );
142 141 }
142 +
143 + $optimized_sizes = self::filter_only_enabled_sizes( $meta->get_optimized_sizes() );
144 + $output['optimized_image_count'] += count( $optimized_sizes );
143 145 }
144 146
145 147 return $output;
146 148 }
147 149
150 + public static function get_optimization_details( int $attachment_id ): array {
151 + try {
152 + $wp_meta = new WP_Image_Meta( $attachment_id );
153 + } catch ( Invalid_Image_Exception $iie ) {
154 + Logger::log( Logger::LEVEL_ERROR, "No metadata found for image ID: {$attachment_id}" );
155 +
156 + throw $iie;
157 + }
158 +
159 + $output = [
160 + 'total' => 0,
161 + 'sizes' => [],
162 + ];
163 +
164 + $meta = new Image_Meta( $attachment_id );
165 + $image_sizes = self::filter_only_enabled_sizes( $wp_meta->get_size_keys() );
166 +
167 + foreach ( $image_sizes as $image_size ) {
168 + $current_image_size = self::calculate_current_image_file_size( $attachment_id, $wp_meta, $image_size );
169 + $output['total'] += $current_image_size;
170 +
171 + $status = self::get_image_size_optimization_status( $attachment_id, $image_size );
172 +
173 + if ( Image_Status::OPTIMIZED === $status ) {
174 + $dimensions_updated = $wp_meta->get_width( $image_size ) !== (int) $meta->get_original_width( $image_size ) ||
175 + $wp_meta->get_height( $image_size ) !== (int) $meta->get_original_height( $image_size );
176 +
177 + $new_dimensions = $dimensions_updated ? [
178 + 'width' => $wp_meta->get_width( $image_size ),
179 + 'height' => $wp_meta->get_height( $image_size ),
180 + ] : null;
181 +
182 + $initial_image_size = self::calculate_initial_image_file_size( $attachment_id, $meta, $wp_meta, $image_size );
183 +
184 + $saved = [
185 + 'relative' => max( 100 - round( $current_image_size / $initial_image_size * 100 ), 0 ),
186 + 'absolute' => $initial_image_size - $current_image_size,
187 + ];
188 + }
189 +
190 + $output['sizes'][] = [
191 + 'size_name' => $image_size,
192 + 'file_size' => $current_image_size,
193 + 'status' => self::get_image_size_optimization_status( $attachment_id, $image_size ),
194 + 'saved' => $saved ?? null,
195 + 'new_dimensions' => $new_dimensions ?? null,
196 + ];
197 + }
198 +
199 + return $output;
200 + }
201 +
202 + private static function get_image_size_optimization_status( int $attachment_id, string $size_name ): string {
203 + $image = new Image( $attachment_id );
204 + $meta = new Image_Meta( $attachment_id );
205 +
206 + if ( in_array( $size_name, $meta->get_optimized_sizes(), true ) ) {
207 + return Image_Status::OPTIMIZED;
208 + }
209 +
210 + if ( ! $image->file_exists( $size_name ) ) {
211 + return 'file-not-found';
212 + }
213 +
214 + try {
215 + Validate_Image::validate_file_size( $attachment_id, $size_name );
216 + } catch ( Image_Validation_Error $ive ) {
217 + return 'file-too-large';
218 + }
219 +
220 + return Image_Status::NOT_OPTIMIZED;
221 + }
222 +
148 223 private static function calculate_current_image_file_size( int $image_id, WP_Image_Meta $wp_meta, string $image_size ): int {
149 224 $size_from_meta = $wp_meta->get_file_size( $image_size );
150 225
151 226 if ( $size_from_meta ) {
@@ -207,9 +282,11 @@
207 282 'initial_image_size' => null,
208 283 'updated_at' => null,
209 284 ];
210 285
211 - return json_decode( get_option( 'image_optimizer_optimization_stats', json_encode( $default ) ), ARRAY_A );
286 + $output = json_decode( get_option( 'image_optimizer_optimization_stats' ), ARRAY_A );
287 +
288 + return is_array( $output ) ? $output : $default;
212 289 }
213 290
214 291 /**
215 292 * Updates the optimization stats with fresh values.
@@ -217,9 +294,9 @@
217 294 * @param array $stats
218 295 *
219 296 * @return bool
220 297 */
221 - public static function set_stored_stats( array $stats ) {
298 + public static function set_stored_stats( array $stats ): bool {
222 299 $stats['updated_at'] = time();
223 300
224 301 return update_option( 'image_optimizer_optimization_stats', json_encode( $stats ) );
225 302 }