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

321 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 '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 Next gen versions.
169 *
170 * @since 2.2
171 *
172 * @param string $format Format we are looking for. (webp|avif).
173 *
174 * @return array {
175 * @type array $ids A list of media IDs.
176 * @type array $errors {
177 * @type array $no_file_path A list of media IDs.
178 * @type array $no_backup A list of media IDs.
179 * }
180 * }
181 */
182 public function get_optimized_media_ids_without_format( $format ) {
183 global $wpdb;
184
185 $this->set_no_time_limit();
186
187 $mime_types = Imagify_DB::get_mime_types( 'image' );
188
189 // Remove single quotes and explode string into array.
190 $mime_types_array = explode( ',', str_replace( "'", '', $mime_types ) );
191
192 // Iterate over array and check if string contains input.
193 foreach ( $mime_types_array as $item ) {
194 if ( strpos( $item, $format ) !== false ) {
195 $mime = $item;
196 break;
197 }
198 }
199 if ( ! isset( $mime ) && empty( $mime ) ) {
200 $mime = 'image/webp';
201 }
202 $mime_types = str_replace( ",'" . $mime . "'", '', $mime_types );
203 $statuses = Imagify_DB::get_post_statuses();
204 $nodata_join = Imagify_DB::get_required_wp_metadata_join_clause();
205 $nodata_where = Imagify_DB::get_required_wp_metadata_where_clause( [
206 'prepared' => true,
207 ] );
208 $nextgen_suffix = constant( imagify_get_optimization_process_class_name( 'wp' ) . '::' . strtoupper( $format ) . '_SUFFIX' );
209
210 $ids = $wpdb->get_col( $wpdb->prepare( // WPCS: unprepared SQL ok.
211 "
212 SELECT p.ID
213 FROM $wpdb->posts AS p
214 $nodata_join
215 LEFT JOIN $wpdb->postmeta AS mt1
216 ON ( p.ID = mt1.post_id AND mt1.meta_key = '_imagify_status' )
217 LEFT JOIN $wpdb->postmeta AS mt2
218 ON ( p.ID = mt2.post_id AND mt2.meta_key = '_imagify_data' )
219 WHERE
220 p.post_mime_type IN ( $mime_types )
221 AND (mt1.meta_key IS NULL OR mt1.meta_value = 'success' OR mt1.meta_value = 'already_optimized' )
222 AND mt2.meta_value NOT LIKE %s
223 AND p.post_type = 'attachment'
224 AND p.post_status IN ( $statuses )
225 $nodata_where
226 ORDER BY p.ID DESC
227 LIMIT 0, %d",
228 '%' . $wpdb->esc_like( $nextgen_suffix . '";a:4:{s:7:"success";b:1;' ) . '%',
229 imagify_get_unoptimized_attachment_limit()
230 ) );
231
232 $wpdb->flush();
233 unset( $mime_types, $statuses, $nextgen_suffix, $mime );
234
235 $ids = array_filter( array_map( 'absint', $ids ) );
236
237 $data = [
238 'ids' => [],
239 'errors' => [
240 'no_file_path' => [],
241 'no_backup' => [],
242 ],
243 ];
244
245 if ( ! $ids ) {
246 return $data;
247 }
248
249 $metas = Imagify_DB::get_metas( [
250 // Get attachments filename.
251 'filenames' => '_wp_attached_file',
252 ], $ids );
253
254 /**
255 * Fires before testing for file existence.
256 *
257 * @since 1.9
258 *
259 * @param array $ids An array of attachment IDs.
260 * @param array $metas An array of the data fetched from the database.
261 * @param string $context The context.
262 */
263 do_action( 'imagify_bulk_generate_nextgen_before_file_existence_tests', $ids, $metas, 'wp' );
264
265 foreach ( $ids as $i => $id ) {
266 if ( empty( $metas['filenames'][ $id ] ) ) {
267 // Problem. Should not happen, thanks to the wpdb query.
268 $data['errors']['no_file_path'][] = $id;
269 continue;
270 }
271
272 $file_path = get_imagify_attached_file( $metas['filenames'][ $id ] );
273
274 if ( ! $file_path ) {
275 // Main file not found.
276 $data['errors']['no_file_path'][] = $id;
277 continue;
278 }
279
280 $backup_path = get_imagify_attachment_backup_path( $file_path );
281
282 if ( ! $this->filesystem->exists( $backup_path ) ) {
283 // No backup, no WebP.
284 $data['errors']['no_backup'][] = $id;
285 continue;
286 }
287
288 $data['ids'][] = $id;
289 } // End foreach().
290
291 return $data;
292 }
293
294 /**
295 * Get the context data.
296 *
297 * @since 1.9
298 *
299 * @return array {
300 * The formated data.
301 *
302 * @type string $count-optimized Number of media optimized.
303 * @type string $count-errors Number of media having an optimization error, with a link to the page listing the optimization errors.
304 * @type string $optimized-size Optimized filesize.
305 * @type string $original-size Original filesize.
306 * }
307 */
308 public function get_context_data() {
309 $total_saving_data = imagify_count_saving_data();
310 $data = [
311 'count-optimized' => imagify_count_optimized_attachments(),
312 'count-errors' => imagify_count_error_attachments(),
313 'optimized-size' => $total_saving_data['optimized_size'],
314 'original-size' => $total_saving_data['original_size'],
315 'errors_url' => get_imagify_admin_url( 'folder-errors', $this->context ),
316 ];
317
318 return $this->format_context_data( $data );
319 }
320 }
321