PluginProbe
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF / 2.1
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF v2.1
2.3.4 2.3.3 2.3.2 2.3.1 2.3.0 2.2.9 2.2.8 trunk 1.10 1.3.3 1.3.4 1.3.5 1.3.5.1 1.3.5.2 1.3.6 1.3.6.1 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.5 All 103 releases
imagify / classes / Bulk / WP.php

WP.php in Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF 2.1, at classes/Bulk/WP.php

303 lines 8.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Imagify\Bulk;
3
4 use Imagify_DB;
5
6 /**
7 * Class to use for bulk for WP attachments.
8 *
9 * @since 1.9
10 */
11 class WP extends AbstractBulk {
12 /**
13 * Context "short name".
14 *
15 * @var string
16 * @since 1.9
17 */
18 protected $context = 'wp';
19
20 /**
21 * Get all unoptimized media ids.
22 *
23 * @since 1.9
24 *
25 * @param int $optimization_level The optimization level.
26 *
27 * @return array A list of unoptimized media IDs.
28 */
29 public function get_unoptimized_media_ids( $optimization_level ) {
30 global $wpdb;
31
32 $this->set_no_time_limit();
33
34 $mime_types = Imagify_DB::get_mime_types();
35 $statuses = Imagify_DB::get_post_statuses();
36 $nodata_join = Imagify_DB::get_required_wp_metadata_join_clause();
37 $nodata_where = Imagify_DB::get_required_wp_metadata_where_clause( [
38 'prepared' => true,
39 ] );
40 $ids = $wpdb->get_col( $wpdb->prepare( // WPCS: unprepared SQL ok.
41 "
42 SELECT DISTINCT p.ID
43 FROM $wpdb->posts AS p
44 $nodata_join
45 LEFT JOIN $wpdb->postmeta AS mt1
46 ON ( p.ID = mt1.post_id AND mt1.meta_key = '_imagify_status' )
47 LEFT JOIN $wpdb->postmeta AS mt2
48 ON ( p.ID = mt2.post_id AND mt2.meta_key = '_imagify_optimization_level' )
49 WHERE
50 p.post_mime_type IN ( $mime_types )
51 AND (
52 mt1.meta_value = 'error'
53 OR
54 mt2.meta_value != %d
55 OR
56 mt2.post_id IS NULL
57 )
58 AND p.post_type = 'attachment'
59 AND p.post_status IN ( $statuses )
60 $nodata_where
61 ORDER BY
62 CASE mt1.meta_value
63 WHEN 'already_optimized' THEN 2
64 ELSE 1
65 END ASC,
66 p.ID DESC
67 LIMIT 0, %d",
68 $optimization_level,
69 imagify_get_unoptimized_attachment_limit()
70 ) );
71
72 $wpdb->flush();
73 unset( $mime_types );
74 $ids = array_filter( array_map( 'absint', $ids ) );
75
76 if ( ! $ids ) {
77 return [];
78 }
79
80 $metas = Imagify_DB::get_metas( [
81 // Get attachments filename.
82 'filenames' => '_wp_attached_file',
83 // Get attachments data.
84 'data' => '_imagify_data',
85 // Get attachments optimization level.
86 'optimization_levels' => '_imagify_optimization_level',
87 // Get attachments status.
88 'statuses' => '_imagify_status',
89 ], $ids );
90
91 // First run.
92 foreach ( $ids as $i => $id ) {
93 $attachment_status = isset( $metas['statuses'][ $id ] ) ? $metas['statuses'][ $id ] : false;
94 $attachment_optimization_level = isset( $metas['optimization_levels'][ $id ] ) ? $metas['optimization_levels'][ $id ] : false;
95 $attachment_error = '';
96
97 if ( isset( $metas['data'][ $id ]['sizes']['full']['error'] ) ) {
98 $attachment_error = $metas['data'][ $id ]['sizes']['full']['error'];
99 }
100
101 // Don't try to re-optimize if the optimization level is still the same.
102 if ( $optimization_level === $attachment_optimization_level && is_string( $attachment_error ) ) {
103 unset( $ids[ $i ] );
104 continue;
105 }
106
107 // Don't try to re-optimize images already compressed.
108 if ( 'already_optimized' === $attachment_status && $attachment_optimization_level >= $optimization_level ) {
109 unset( $ids[ $i ] );
110 continue;
111 }
112
113 $attachment_error = trim( $attachment_error );
114
115 // Don't try to re-optimize images with an empty error message.
116 if ( 'error' === $attachment_status && empty( $attachment_error ) ) {
117 unset( $ids[ $i ] );
118 }
119 }
120
121 if ( ! $ids ) {
122 return [];
123 }
124
125 $ids = array_values( $ids );
126
127 /**
128 * Fires before testing for file existence.
129 *
130 * @since 1.6.7
131 *
132 * @param array $ids An array of attachment IDs.
133 * @param array $metas An array of the data fetched from the database.
134 * @param int $optimization_level The optimization level that will be used for the optimization.
135 */
136 do_action( 'imagify_bulk_optimize_before_file_existence_tests', $ids, $metas, $optimization_level );
137
138 $data = [];
139
140 foreach ( $ids as $i => $id ) {
141 if ( empty( $metas['filenames'][ $id ] ) ) {
142 // Problem.
143 continue;
144 }
145
146 $file_path = get_imagify_attached_file( $metas['filenames'][ $id ] );
147
148 if ( ! $file_path || ! $this->filesystem->exists( $file_path ) ) {
149 continue;
150 }
151
152 $attachment_backup_path = get_imagify_attachment_backup_path( $file_path );
153 $attachment_status = isset( $metas['statuses'][ $id ] ) ? $metas['statuses'][ $id ] : false;
154 $attachment_optimization_level = isset( $metas['optimization_levels'][ $id ] ) ? $metas['optimization_levels'][ $id ] : false;
155
156 // Don't try to re-optimize if there is no backup file.
157 if ( 'success' === $attachment_status && $optimization_level !== $attachment_optimization_level && ! $this->filesystem->exists( $attachment_backup_path ) ) {
158 continue;
159 }
160
161 $data[] = $id;
162 } // End foreach().
163
164 return $data;
165 }
166
167 /**
168 * Get ids of all optimized media without WebP versions.
169 *
170 * @since 1.9
171 * @since 1.9.5 The method doesn't return the IDs directly anymore.
172 *
173 * @return array {
174 * @type array $ids A list of media IDs.
175 * @type array $errors {
176 * @type array $no_file_path A list of media IDs.
177 * @type array $no_backup A list of media IDs.
178 * }
179 * }
180 */
181 public function get_optimized_media_ids_without_webp() {
182 global $wpdb;
183
184 $this->set_no_time_limit();
185
186 $mime_types = Imagify_DB::get_mime_types( 'image' );
187 $statuses = Imagify_DB::get_post_statuses();
188 $nodata_join = Imagify_DB::get_required_wp_metadata_join_clause();
189 $nodata_where = Imagify_DB::get_required_wp_metadata_where_clause( [
190 'prepared' => true,
191 ] );
192 $webp_suffix = constant( imagify_get_optimization_process_class_name( 'wp' ) . '::WEBP_SUFFIX' );
193 $ids = $wpdb->get_col( $wpdb->prepare( // WPCS: unprepared SQL ok.
194 "
195 SELECT p.ID
196 FROM $wpdb->posts AS p
197 $nodata_join
198 LEFT JOIN $wpdb->postmeta AS mt1
199 ON ( p.ID = mt1.post_id AND mt1.meta_key = '_imagify_status' )
200 LEFT JOIN $wpdb->postmeta AS mt2
201 ON ( p.ID = mt2.post_id AND mt2.meta_key = '_imagify_data' )
202 WHERE
203 p.post_mime_type IN ( $mime_types )
204 AND ( mt1.meta_value = 'success' OR mt1.meta_value = 'already_optimized' )
205 AND mt2.meta_value NOT LIKE %s
206 AND p.post_type = 'attachment'
207 AND p.post_status IN ( $statuses )
208 $nodata_where
209 ORDER BY p.ID DESC
210 LIMIT 0, %d",
211 '%' . $wpdb->esc_like( $webp_suffix . '";a:4:{s:7:"success";b:1;' ) . '%',
212 imagify_get_unoptimized_attachment_limit()
213 ) );
214
215 $wpdb->flush();
216 unset( $mime_types, $statuses, $webp_suffix );
217
218 $ids = array_filter( array_map( 'absint', $ids ) );
219 $data = [
220 'ids' => [],
221 'errors' => [
222 'no_file_path' => [],
223 'no_backup' => [],
224 ],
225 ];
226
227 if ( ! $ids ) {
228 return $data;
229 }
230
231 $metas = Imagify_DB::get_metas( [
232 // Get attachments filename.
233 'filenames' => '_wp_attached_file',
234 ], $ids );
235
236 /**
237 * Fires before testing for file existence.
238 *
239 * @since 1.9
240 *
241 * @param array $ids An array of attachment IDs.
242 * @param array $metas An array of the data fetched from the database.
243 * @param string $context The context.
244 */
245 do_action( 'imagify_bulk_generate_webp_before_file_existence_tests', $ids, $metas, 'wp' );
246
247 foreach ( $ids as $i => $id ) {
248 if ( empty( $metas['filenames'][ $id ] ) ) {
249 // Problem. Should not happen, thanks to the wpdb query.
250 $data['errors']['no_file_path'][] = $id;
251 continue;
252 }
253
254 $file_path = get_imagify_attached_file( $metas['filenames'][ $id ] );
255
256 if ( ! $file_path ) {
257 // Main file not found.
258 $data['errors']['no_file_path'][] = $id;
259 continue;
260 }
261
262 $backup_path = get_imagify_attachment_backup_path( $file_path );
263
264 if ( ! $this->filesystem->exists( $backup_path ) ) {
265 // No backup, no WebP.
266 $data['errors']['no_backup'][] = $id;
267 continue;
268 }
269
270 $data['ids'][] = $id;
271 } // End foreach().
272
273 return $data;
274 }
275
276 /**
277 * Get the context data.
278 *
279 * @since 1.9
280 *
281 * @return array {
282 * The formated data.
283 *
284 * @type string $count-optimized Number of media optimized.
285 * @type string $count-errors Number of media having an optimization error, with a link to the page listing the optimization errors.
286 * @type string $optimized-size Optimized filesize.
287 * @type string $original-size Original filesize.
288 * }
289 */
290 public function get_context_data() {
291 $total_saving_data = imagify_count_saving_data();
292 $data = [
293 'count-optimized' => imagify_count_optimized_attachments(),
294 'count-errors' => imagify_count_error_attachments(),
295 'optimized-size' => $total_saving_data['optimized_size'],
296 'original-size' => $total_saving_data['original_size'],
297 'errors_url' => get_imagify_admin_url( 'folder-errors', $this->context ),
298 ];
299
300 return $this->format_context_data( $data );
301 }
302 }
303