PluginProbe
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF / 2.2.8
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF v2.2.8
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.2.8, at classes/Bulk/WP.php

340 lines 9.2 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 [
39 'prepared' => true,
40 ]
41 );
42 $ids = $wpdb->get_col(
43 $wpdb->prepare( // WPCS: unprepared SQL ok.
44 "
45 SELECT DISTINCT p.ID
46 FROM $wpdb->posts AS p
47 $nodata_join
48 LEFT JOIN $wpdb->postmeta AS mt1
49 ON ( p.ID = mt1.post_id AND mt1.meta_key = '_imagify_status' )
50 LEFT JOIN $wpdb->postmeta AS mt2
51 ON ( p.ID = mt2.post_id AND mt2.meta_key = '_imagify_optimization_level' )
52 WHERE
53 p.post_mime_type IN ( $mime_types )
54 AND (
55 mt1.meta_value = 'error'
56 OR
57 mt2.meta_value != %d
58 OR
59 mt2.post_id IS NULL
60 )
61 AND p.post_type = 'attachment'
62 AND p.post_status IN ( $statuses )
63 $nodata_where
64 ORDER BY
65 CASE mt1.meta_value
66 WHEN 'already_optimized' THEN 2
67 ELSE 1
68 END ASC,
69 p.ID DESC
70 LIMIT 0, %d",
71 $optimization_level,
72 imagify_get_unoptimized_attachment_limit()
73 )
74 );
75
76 $wpdb->flush();
77 unset( $mime_types );
78 $ids = array_filter( array_map( 'absint', $ids ) );
79
80 if ( ! $ids ) {
81 return [];
82 }
83
84 $metas = Imagify_DB::get_metas(
85 [
86 // Get attachments filename.
87 'filenames' => '_wp_attached_file',
88 // Get attachments data.
89 'data' => '_imagify_data',
90 // Get attachments optimization level.
91 'optimization_levels' => '_imagify_optimization_level',
92 // Get attachments status.
93 'statuses' => '_imagify_status',
94 ],
95 $ids
96 );
97
98 // First run.
99 foreach ( $ids as $i => $id ) {
100 $attachment_status = isset( $metas['statuses'][ $id ] ) ? $metas['statuses'][ $id ] : false;
101 $attachment_optimization_level = isset( $metas['optimization_levels'][ $id ] ) ? $metas['optimization_levels'][ $id ] : false;
102 $attachment_error = '';
103
104 if ( isset( $metas['data'][ $id ]['sizes']['full']['error'] ) ) {
105 $attachment_error = $metas['data'][ $id ]['sizes']['full']['error'];
106 }
107
108 // Don't try to re-optimize if the optimization level is still the same.
109 if ( $optimization_level === $attachment_optimization_level && is_string( $attachment_error ) ) {
110 unset( $ids[ $i ] );
111 continue;
112 }
113
114 // Don't try to re-optimize images already compressed.
115 if ( 'already_optimized' === $attachment_status && $attachment_optimization_level >= $optimization_level ) {
116 unset( $ids[ $i ] );
117 continue;
118 }
119
120 $attachment_error = trim( $attachment_error );
121
122 // Don't try to re-optimize images with an empty error message.
123 if ( 'error' === $attachment_status && empty( $attachment_error ) ) {
124 unset( $ids[ $i ] );
125 }
126 }
127
128 if ( ! $ids ) {
129 return [];
130 }
131
132 $ids = array_values( $ids );
133
134 /**
135 * Fires before testing for file existence.
136 *
137 * @since 1.6.7
138 *
139 * @param array $ids An array of attachment IDs.
140 * @param array $metas An array of the data fetched from the database.
141 * @param int $optimization_level The optimization level that will be used for the optimization.
142 */
143 do_action( 'imagify_bulk_optimize_before_file_existence_tests', $ids, $metas, $optimization_level );
144
145 $data = [];
146
147 foreach ( $ids as $i => $id ) {
148 if ( empty( $metas['filenames'][ $id ] ) ) {
149 // Problem.
150 continue;
151 }
152
153 $file_path = get_imagify_attached_file( $metas['filenames'][ $id ] );
154
155 if ( ! $file_path || ! $this->filesystem->exists( $file_path ) ) {
156 continue;
157 }
158
159 $attachment_backup_path = get_imagify_attachment_backup_path( $file_path );
160 $attachment_status = isset( $metas['statuses'][ $id ] ) ? $metas['statuses'][ $id ] : false;
161 $attachment_optimization_level = isset( $metas['optimization_levels'][ $id ] ) ? $metas['optimization_levels'][ $id ] : false;
162
163 // Don't try to re-optimize if there is no backup file.
164 if ( 'success' === $attachment_status && $optimization_level !== $attachment_optimization_level && ! $this->filesystem->exists( $attachment_backup_path ) ) {
165 continue;
166 }
167
168 $data[] = $id;
169 }
170
171 return $data;
172 }
173
174 /**
175 * Get ids of all optimized media without Next gen versions.
176 *
177 * @since 2.2
178 *
179 * @param string $format Format we are looking for. (webp|avif).
180 *
181 * @return array {
182 * @type array $ids A list of media IDs.
183 * @type array $errors {
184 * @type array $no_file_path A list of media IDs.
185 * @type array $no_backup A list of media IDs.
186 * }
187 * }
188 */
189 public function get_optimized_media_ids_without_format( $format ) {
190 global $wpdb;
191
192 $this->set_no_time_limit();
193
194 $mime_types = Imagify_DB::get_mime_types( 'image' );
195
196 // Remove single quotes and explode string into array.
197 $mime_types_array = explode( ',', str_replace( "'", '', $mime_types ) );
198
199 // Iterate over array and check if string contains input.
200 foreach ( $mime_types_array as $item ) {
201 if ( strpos( $item, $format ) !== false ) {
202 $mime = $item;
203 break;
204 }
205 }
206 if ( ! isset( $mime ) && empty( $mime ) ) {
207 $mime = 'image/webp';
208 }
209 $mime_types = str_replace( ",'" . $mime . "'", '', $mime_types );
210 $statuses = Imagify_DB::get_post_statuses();
211 $nodata_join = '';
212 $nodata_where = '';
213 if ( ! imagify_has_attachments_without_required_metadata() ) {
214 $nodata_join = Imagify_DB::get_required_wp_metadata_join_clause();
215 $nodata_where = Imagify_DB::get_required_wp_metadata_where_clause(
216 [
217 'prepared' => true,
218 ]
219 );
220 }
221
222 $nextgen_suffix = constant( imagify_get_optimization_process_class_name( 'wp' ) . '::' . strtoupper( $format ) . '_SUFFIX' );
223
224 $ids = $wpdb->get_col(
225 $wpdb->prepare( // WPCS: unprepared SQL ok.
226 "
227 SELECT p.ID
228 FROM $wpdb->posts AS p
229 $nodata_join
230 LEFT JOIN $wpdb->postmeta AS mt1
231 ON ( p.ID = mt1.post_id AND mt1.meta_key = '_imagify_status' )
232 LEFT JOIN $wpdb->postmeta AS mt2
233 ON ( p.ID = mt2.post_id AND mt2.meta_key = '_imagify_data' )
234 WHERE
235 p.post_mime_type IN ( $mime_types )
236 AND (mt1.meta_key IS NULL OR mt1.meta_value = 'success' OR mt1.meta_value = 'already_optimized' )
237 AND mt2.meta_value NOT LIKE %s
238 AND p.post_type = 'attachment'
239 AND p.post_status IN ( $statuses )
240 $nodata_where
241 ORDER BY p.ID DESC
242 LIMIT 0, %d",
243 '%' . $wpdb->esc_like( $nextgen_suffix . '";a:4:{s:7:"success";b:1;' ) . '%',
244 imagify_get_unoptimized_attachment_limit()
245 )
246 );
247
248 $wpdb->flush();
249 unset( $mime_types, $statuses, $nextgen_suffix, $mime );
250
251 $ids = array_filter( array_map( 'absint', $ids ) );
252
253 $data = [
254 'ids' => [],
255 'errors' => [
256 'no_file_path' => [],
257 'no_backup' => [],
258 ],
259 ];
260
261 if ( ! $ids ) {
262 return $data;
263 }
264
265 $metas = Imagify_DB::get_metas(
266 [
267 // Get attachments filename.
268 'filenames' => '_wp_attached_file',
269 ],
270 $ids
271 );
272
273 /**
274 * Fires before testing for file existence.
275 *
276 * @since 1.9
277 *
278 * @param array $ids An array of attachment IDs.
279 * @param array $metas An array of the data fetched from the database.
280 * @param string $context The context.
281 */
282 do_action( 'imagify_bulk_generate_nextgen_before_file_existence_tests', $ids, $metas, 'wp' );
283
284 foreach ( $ids as $i => $id ) {
285 if ( empty( $metas['filenames'][ $id ] ) ) {
286 // Problem. Should not happen, thanks to the wpdb query.
287 $data['errors']['no_file_path'][] = $id;
288 continue;
289 }
290
291 $file_path = get_imagify_attached_file( $metas['filenames'][ $id ] );
292
293 if ( ! $file_path ) {
294 // Main file not found.
295 $data['errors']['no_file_path'][] = $id;
296 continue;
297 }
298
299 $backup_path = get_imagify_attachment_backup_path( $file_path );
300
301 if ( ! $this->filesystem->exists( $backup_path ) ) {
302 // No backup, no WebP.
303 $data['errors']['no_backup'][] = $id;
304 continue;
305 }
306
307 $data['ids'][] = $id;
308 }
309
310 return $data;
311 }
312
313 /**
314 * Get the context data.
315 *
316 * @since 1.9
317 *
318 * @return array {
319 * The formated data.
320 *
321 * @type string $count-optimized Number of media optimized.
322 * @type string $count-errors Number of media having an optimization error, with a link to the page listing the optimization errors.
323 * @type string $optimized-size Optimized filesize.
324 * @type string $original-size Original filesize.
325 * }
326 */
327 public function get_context_data() {
328 $total_saving_data = imagify_count_saving_data();
329 $data = [
330 'count-optimized' => imagify_count_optimized_attachments(),
331 'count-errors' => imagify_count_error_attachments(),
332 'optimized-size' => $total_saving_data['optimized_size'],
333 'original-size' => $total_saving_data['original_size'],
334 'errors_url' => get_imagify_admin_url( 'folder-errors', $this->context ),
335 ];
336
337 return $this->format_context_data( $data );
338 }
339 }
340