PluginProbe
Image Optimizer – Compress Images and Convert to WebP or AVIF / 1.2.1
Image Optimizer – Compress Images and Convert to WebP or AVIF v1.2.1
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
image-optimization / modules / stats / classes / optimization-stats.php

optimization-stats.php in Image Optimizer – Compress Images and Convert to WebP or AVIF 1.2.1, at modules/stats/classes/optimization-stats.php

159 lines 4.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace ImageOptimization\Modules\Stats\Classes;
4
5 use ImageOptimization\Classes\Image\{
6 Image,
7 Image_Meta,
8 Image_Query_Builder,
9 WP_Image_Meta,
10 Exceptions\Invalid_Image_Exception
11 };
12 use ImageOptimization\Classes\File_System\Exceptions\File_System_Operation_Error;
13 use ImageOptimization\Classes\File_System\File_System;
14 use ImageOptimization\Classes\Logger;
15 use ImageOptimization\Modules\Optimization\Classes\Exceptions\Image_Validation_Error;
16 use ImageOptimization\Modules\Optimization\Classes\Validate_Image;
17 use ImageOptimization\Modules\Settings\Classes\Settings;
18
19 if ( ! defined( 'ABSPATH' ) ) {
20 exit; // Exit if accessed directly.
21 }
22
23 class Optimization_Stats {
24 const PAGING_SIZE = 25000;
25
26 /**
27 * Returns image stats.
28 * If the library is too big, it queries images in chunks.
29 *
30 * @return array{total_image_count: int, optimized_image_count: int, current_image_size: int, initial_image_size:
31 * int}
32 */
33 public static function get_image_stats( ?int $image_id = null ): array {
34 $output = self::get_image_stats_chunk( 1, $image_id );
35 $pages_count = $output['pages'];
36
37 if ( $pages_count > 1 ) {
38 // $i initially is 2 bc we already got the first page, so we don't have to query it again
39 for ( $i = 2; $i <= $pages_count; $i ++ ) {
40 $chunk = self::get_image_stats_chunk( $i );
41
42 foreach ( array_keys( $chunk ) as $key ) {
43 if ( isset( $output[ $key ] ) ) {
44 $output[ $key ] += $chunk[ $key ];
45 continue;
46 }
47
48 $output[ $key ] = $chunk[ $key ];
49 }
50 }
51 }
52
53 unset( $output['pages'] );
54
55 return $output;
56 }
57
58 /**
59 * @return array{pages: int, total_image_count: int, optimized_image_count: int, current_image_size: int,
60 * initial_image_size: int}
61 */
62 public static function get_image_stats_chunk( int $paged = 1, ?int $image_id = null ): array {
63 $output = [
64 'pages' => 1,
65 'total_image_count' => 0,
66 'optimized_image_count' => 0,
67 'current_image_size' => 0,
68 'initial_image_size' => 0,
69 ];
70
71 $query = ( new Image_Query_Builder() )
72 ->set_paging_size( self::PAGING_SIZE )
73 ->set_current_page( $paged );
74
75 if ( $image_id ) {
76 $query->set_image_ids( [ $image_id ] );
77 }
78
79 $query = $query->execute();
80
81 $output['pages'] = $query->max_num_pages;
82
83 foreach ( $query->posts as $attachment_id ) {
84 try {
85 Validate_Image::is_valid( $attachment_id );
86 $wp_meta = new WP_Image_Meta( $attachment_id );
87 } catch ( Invalid_Image_Exception |Image_Validation_Error $ie ) {
88 Logger::log( Logger::LEVEL_ERROR, $ie->getMessage() );
89
90 continue;
91 }
92
93 $meta = new Image_Meta( $attachment_id );
94 $image_sizes = $wp_meta->get_size_keys();
95
96 $current_sizes = self::filter_only_enabled_sizes( $image_sizes );
97 $optimized_sizes = self::filter_only_enabled_sizes( $meta->get_optimized_sizes() );
98
99 $output['total_image_count'] += count( $current_sizes );
100 $output['optimized_image_count'] += count( $optimized_sizes );
101
102 foreach ( $image_sizes as $image_size ) {
103 $output['current_image_size'] += self::calculate_current_image_file_size( $attachment_id, $wp_meta, $image_size );
104 $output['initial_image_size'] += self::calculate_initial_image_file_size( $attachment_id, $meta, $wp_meta, $image_size );
105 }
106 }
107
108 return $output;
109 }
110
111 private static function calculate_current_image_file_size( int $image_id, WP_Image_Meta $wp_meta, string $image_size ): int {
112 $size_from_meta = $wp_meta->get_file_size( $image_size );
113
114 if ( $size_from_meta ) {
115 return $size_from_meta;
116 }
117
118 try {
119 return File_System::size( ( new Image( $image_id ) )->get_file_path( $image_size ) );
120 } catch ( File_System_Operation_Error $e ) {
121 return 0;
122 }
123 }
124
125 private static function calculate_initial_image_file_size( int $image_id, Image_Meta $meta, WP_Image_Meta $wp_meta, string $image_size ): int {
126 $size_from_meta = $meta->get_original_file_size( $image_size ) ?? $wp_meta->get_file_size( $image_size );
127
128 if ( $size_from_meta ) {
129 return $size_from_meta;
130 }
131
132 try {
133 return File_System::size( ( new Image( $image_id ) )->get_file_path( $image_size ) );
134 } catch ( File_System_Operation_Error $e ) {
135 return 0;
136 }
137 }
138
139 private static function filter_only_enabled_sizes( array $size_keys ): array {
140 $enabled_sizes = Settings::get( Settings::CUSTOM_SIZES_OPTION_NAME );
141
142 if ( 'all' === $enabled_sizes ) {
143 return array_filter( $size_keys, fn( string $size_key ) => ! str_starts_with( $size_key, 'elementor_' ) );
144 }
145
146 return array_filter($size_keys, function( string $size ) use ( $enabled_sizes ) {
147 if ( Image::SIZE_FULL === $size ) {
148 return true;
149 }
150
151 if ( in_array( $size, $enabled_sizes, true ) ) {
152 return true;
153 }
154
155 return false;
156 });
157 }
158 }
159