PluginProbe
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance / 4.7.0
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance v4.7.0
4.7.0 4.6.1 4.6.0 4.5.5 4.5.4 4.5.3 4.5.2 3.2.20 3.2.21 3.2.22 3.2.3 3.2.5 3.2.6 3.2.7 3.2.9 3.3.0 3.3.1 3.3.2 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.7.0 3.7.1 All 111 releases
← All changes | includes/class-updraft-smush-manager.php +444 -300 3.2.22 → 4.7.0 View file →
@@ -74,11 +74,10 @@
74 74 add_action('ud_task_completed', array($this, 'record_stats'));
75 75 add_action('ud_task_failed', array($this, 'record_stats'));
76 76 add_action('prune_smush_logs', array($this, 'prune_smush_logs'));
77 77 add_action('process_smush_tasks', array($this, 'process_smush_tasks'));
78 - if ('show' == $this->options->get_option('show_smush_metabox', 'show')) {
78 + if ('show' === $this->options->get_option('show_smush_metabox', 'show')) {
79 79 add_action('add_meta_boxes_attachment', array($this, 'add_smush_metabox'), 10, 2);
80 - add_filter('attachment_fields_to_edit', array($this, 'add_compress_button_to_media_modal' ), 10, 2);
81 80 }
82 81 add_action('delete_attachment', array($this, 'unscheduled_original_file_deletion'));
83 82
84 83 add_filter('manage_media_columns', array($this, 'manage_media_columns'));
@@ -89,9 +88,9 @@
89 88
90 89 // add filter for already compressed images by EWWW Image Optimizer.
91 90 add_filter('wpo_get_uncompressed_images_args', array($this, 'ewww_image_optimizer_compressed_images_args'));
92 91
93 - // schedule or unschedule clear backup images cron if need
92 + // schedule or unschedule clear backup images cron, if needed
94 93 $scheduled = wp_next_scheduled('wpo_smush_clear_backup_images');
95 94 if ($this->options->get_option('back_up_delete_after', true)) {
96 95 if (!$scheduled) {
97 96 wp_schedule_event(time(), 'daily', 'wpo_smush_clear_backup_images');
@@ -100,8 +99,14 @@
100 99 if ($scheduled) {
101 100 wp_unschedule_event($scheduled, 'wpo_smush_clear_backup_images');
102 101 }
103 102 }
103 +
104 + // Schedule CRON job for deleting failed smush tasks
105 + add_action('wpo_smush_clear_failed_tasks', array($this, 'clear_failed_tasks'));
106 + if (!wp_next_scheduled('wpo_smush_clear_failed_tasks')) {
107 + wp_schedule_event(time(), 'wpo_monthly', 'wpo_smush_clear_failed_tasks');
108 + }
104 109 }
105 110
106 111 /**
107 112 * Add custom column to Media Library.
@@ -106,9 +111,9 @@
106 111 /**
107 112 * Add custom column to Media Library.
108 113 *
109 114 * @param array $columns
110 - * @return mixed
115 + * @return array
111 116 */
112 117 public function manage_media_columns($columns) {
113 118 $columns['wpo_smush'] = 'WP-Optimize';
114 119
@@ -122,48 +127,88 @@
122 127 * @param int $attachment_id
123 128 */
124 129 public function manage_media_custom_column($column, $attachment_id) {
125 130 if ('wpo_smush' !== $column) return;
131 + echo $this->get_smush_details($attachment_id); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Output already escaped when generating smush details
132 + }
133 +
134 + /**
135 + * Get smush details of given image ID
136 + *
137 + * @param int $attachment_id
138 + *
139 + * @return string smush details
140 + */
141 + public function get_smush_details($attachment_id) {
142 + $info = '<div class="wpo-smush-media-library-column" data-blog="'.esc_attr(get_current_blog_id()).'" data-id="'.esc_attr($attachment_id).'">';
143 + $info .= $this->get_media_smush_column_content($attachment_id);
144 + $info .= '</div>';
126 145
146 + return $info;
147 + }
148 +
149 + /**
150 + * Get content for Media Library column.
151 + *
152 + * @param int $attachment_id
153 + *
154 + * @return string
155 + */
156 + public function get_media_smush_column_content($attachment_id) {
127 157 $file = get_attached_file($attachment_id);
158 + if (false === $file) {
159 + return '';
160 + }
128 161 $ext = WPO_Image_Utils::get_extension($file);
129 162 $allowed_extensions = WPO_Image_Utils::get_allowed_extensions();
130 163
131 - $smush_stats = get_post_meta($attachment_id, 'smush-stats', true);
164 + $compressed = get_post_meta($attachment_id, '_wpo-smush-complete', true) ? true : false;
165 + $has_backup = get_post_meta($attachment_id, '_wpo-original-file', true) ? true : false;
132 166
133 - if (empty($smush_stats)) {
134 - if ($this->is_compressed($attachment_id)) {
135 - _e('The file was either compressed using another tool or marked as compressed', 'wp-optimize');
136 - } else {
137 - if (in_array($ext, $allowed_extensions) && file_exists($file)) {
138 - printf('<a href="%1$s">%2$s</a><br>', admin_url("post.php?post=" . (int) $attachment_id . "&action=edit"), __('Compress', 'wp-optimize'));
139 - }
140 - }
141 - return;
167 + $smush_info = get_post_meta($attachment_id, '_wpo-smush-info', true);
168 + $smush_stats = get_post_meta($attachment_id, '_wpo-smush-stats', true);
169 + $marked = get_post_meta($attachment_id, '_wpo-smush-marked');
170 +
171 + $extract = array(
172 + 'blog_id' => get_current_blog_id(),
173 + 'post_id' => $attachment_id,
174 + 'smush_info_display'=> $compressed ? "display:inline-block;" : "display:none;",
175 + 'smush_display' => $compressed ? "display:none;" : "display:inline-block;",
176 + 'before_smush_sep' => !$compressed ? '<span class="wpo-action-separator"> | </span>' : '',
177 + 'restore_action' => $has_backup && $compressed ? "display:block;" : "display:none;",
178 + 'smush_mark' => !$compressed && !$marked ? "display:inline-block;" : "display:none;",
179 + 'smush_unmark' => $marked ? "display:inline-block;" : "display:none;",
180 + 'smush_info' => $smush_info ?: ' ',
181 + 'smush_details' => '',
182 + 'restore_tooltip' => $this->get_restore_image_tooltip_text(),
183 + 'smush_marked' => $marked,
184 + );
185 +
186 + if (!empty($smush_stats['sizes-info'])) {
187 + $extract['smush_details'] = WP_Optimize()->include_template('images/smush-details.php', true, array('sizes_info' => $smush_stats['sizes-info']));
142 188 }
143 189
144 - if (WPO_Image_Utils::is_supported_extension($ext, array_diff($allowed_extensions, array('gif'))) && file_exists($file) && !file_exists($file . '.webp')) {
145 - if (WPO_WebP_Utils::can_do_webp_conversion()) {
146 - printf('<a href="#" class="convert-to-webp" data-attachment-id="%d">%s</a><br>', $attachment_id, __('Convert to WebP', 'wp-optimize'));
147 - }
148 - }
190 + $extract['compressed_by_another_plugin'] = $this->is_image_compressed_by_another_plugin($attachment_id);
149 191
150 - $original_size = $smush_stats['original-size'];
151 - $smushed_size = $smush_stats['smushed-size'];
192 + $output = '';
152 193
153 - if (0 == $original_size) {
154 - $info = sprintf(__('The file was compressed to %s using WP-Optimize', 'wp-optimize'), WP_Optimize()->format_size($smushed_size));
194 + if (WPO_Image_Utils::is_supported_extension($ext, $allowed_extensions)) {
195 + $output .= WP_Optimize()->include_template('admin-medialibrary-smush-column.php', true, $extract);
155 196 } else {
156 - $saved = round((($original_size - $smushed_size) / $original_size * 100), 2);
157 - $info = sprintf(__('The file was compressed from %s to %s, saving %s percent, using WP-Optimize', 'wp-optimize'), WP_Optimize()->format_size($original_size), WP_Optimize()->format_size($smushed_size), $saved);
197 + $message = __('Compressing this file type extension is not supported', 'wp-optimize');
198 + $output .= sprintf("<p>%s</p>", esc_html($message));
199 +
158 200 }
159 201
160 - echo htmlentities($info);
202 + if (WPO_Image_Utils::is_supported_extension($ext, array_diff($allowed_extensions, array('gif'))) && file_exists($file) && !file_exists($file . '.webp')) {
203 + if (WPO_WebP_Utils::can_do_webp_conversion()) {
204 + $link_text = __('Convert to WebP', 'wp-optimize');
205 + $output .= '<span class="wpo-action-separator"> | </span>';
206 + $output .= sprintf('<a href="#" class="convert-to-webp" data-attachment-id="%d">%s</a><br>', esc_attr($attachment_id), esc_html($link_text));
207 + }
208 + }
161 209
162 - // Display additional information about resized images.
163 - if (!empty($smush_stats['sizes-info'])) {
164 - WP_Optimize()->include_template('images/smush-details.php', false, array('sizes_info' => $smush_stats['sizes-info']));
165 - }
210 + return $output;
166 211 }
167 212
168 213 /**
169 214 * The Task Manager AJAX handler
@@ -169,25 +214,25 @@
169 214 * The Task Manager AJAX handler
170 215 */
171 216 public function updraft_smush_ajax() {
172 217
173 - $nonce = empty($_REQUEST['nonce']) ? '' : $_REQUEST['nonce'];
218 + $nonce = TeamUpdraft\WP_Optimize\Includes\Fragments\verify_nonce('nonce', 'updraft-task-manager-ajax-nonce');
219 + $subaction = TeamUpdraft\WP_Optimize\Includes\Fragments\fetch_superglobal('request', 'subaction', null, 'sanitize_key');
220 + $data = TeamUpdraft\WP_Optimize\Includes\Fragments\fetch_superglobal('request', 'data');
174 221
175 - if (!wp_verify_nonce($nonce, 'updraft-task-manager-ajax-nonce') || empty($_REQUEST['subaction']))
222 + if (empty($nonce) || empty($subaction)) {
176 223 die('Security check failed');
224 + }
177 225
178 - if (!current_user_can(WP_Optimize()->capability_required())) {
226 + if (!WP_Optimize()->current_user_can()) {
179 227 die('You are not allowed to run this command.');
180 228 }
181 229
182 - $subaction = $_REQUEST['subaction'];
183 -
184 230 $allowed_commands = Updraft_Smush_Manager_Commands::get_allowed_ajax_commands();
185 231
186 232 if (in_array($subaction, $allowed_commands)) {
187 233
188 - if (isset($_REQUEST['data'])) {
189 - $data = $_REQUEST['data'];
234 + if ($data) {
190 235 $results = call_user_func(array($this->commands, $subaction), $data);
191 236 } else {
192 237 $results = call_user_func(array($this->commands, $subaction));
193 238 }
@@ -201,13 +246,13 @@
201 246 'error_data' => $results->get_error_data(),
202 247 );
203 248 }
204 249
205 - echo json_encode($results);
250 + echo wp_json_encode($results);
206 251 } else {
207 - echo json_encode(array('error' => 'No such command found'));
252 + echo wp_json_encode(array('error' => 'No such command found'));
208 253 }
209 - die;
254 + die();
210 255 }
211 256
212 257 /**
213 258 * Creates a task to auto compress an image on upload
@@ -222,28 +267,22 @@
222 267 $allowed_extensions = WPO_Image_Utils::get_allowed_extensions();
223 268
224 269 if(!in_array($ext, $allowed_extensions)) return;
225 270
226 - if (!$this->options->get_option('autosmush', false))
271 + if (!$this->options->get_option('autosmush'))
227 272 return;
228 273
229 - if (!'image' == substr($post->post_mime_type, 0, 5))
274 + if ('image' !== substr($post->post_mime_type, 0, 5))
230 275 return;
231 276
232 277 if ($this->task_exists($post_id))
233 278 return;
234 -
235 - $options = array(
236 - 'attachment_id' => $post_id,
237 - 'blog_id' => get_current_blog_id(),
238 - 'image_quality' => $this->options->get_option('image_quality', 92),
239 - 'keep_original' => $this->options->get_option('back_up_original', true),
240 - 'preserve_exif' => $this->options->get_option('preserve_exif', true),
241 - 'lossy_compression' => $this->options->get_option('lossy_compression', false)
242 - );
243 279
280 + $task_options = $this->get_smush_options();
281 + $task_options = array_merge($task_options, array('attachment_id' => $post_id, 'blog_id' => get_current_blog_id()));
282 +
244 283 if (filesize($file) > 5242880) {
245 - $options['request_timeout'] = 180;
284 + $task_options['request_timeout'] = 180;
246 285 }
247 286
248 287 $server = $this->options->get_option('compression_server', $this->webservice);
249 288 $task_name = $this->get_associated_task($server);
@@ -248,11 +287,11 @@
248 287 $server = $this->options->get_option('compression_server', $this->webservice);
249 288 $task_name = $this->get_associated_task($server);
250 289
251 290 $blog_info = is_multisite() ? ', blog ID : '.get_current_blog_id() : '';
252 - $description = "$task_name with attachment ID : ".$post_id . $blog_info .", autocreated on : ".date("F d, Y h:i:s", time());
291 + $description = "$task_name with attachment ID : ".$post_id . $blog_info .", auto created on : ".gmdate("F d, Y h:i:s", time());
253 292
254 - $task = call_user_func(array($task_name, 'create_task'), 'smush', $description, $options, $task_name);
293 + $task = call_user_func(array($task_name, 'create_task'), 'smush', $description, $task_options, $task_name);
255 294
256 295 if ($task) $this->set_task_logger($task);
257 296 $this->log($description);
258 297
@@ -299,14 +338,14 @@
299 338 * @param int $image - ID of image
300 339 * @param array $options - options to use
301 340 * @param string $server - the server to process with
302 341 *
303 - * @return boolean - Status of the task
342 + * @return bool | WP_Error - Status of the task
304 343 */
305 344 public function compress_single_image($image, $options, $server) {
306 345 $task_name = $this->get_associated_task($server);
307 346 $blog_info = is_multisite() ? ', blog ID : '.get_current_blog_id() : '';
308 - $description = "$task_name - attachment ID : ". $image . $blog_info. ", started on : ". date("F d, Y h:i:s", time());
347 + $description = "$task_name - attachment ID : ". $image . $blog_info. ", started on : ". gmdate("F d, Y h:i:s", time());
309 348
310 349 $task = call_user_func(array($task_name, 'create_task'), 'smush', $description, $options, $task_name);
311 350 if ($task) $this->set_task_logger($task);
312 351 $this->clear_cached_data();
@@ -328,9 +367,9 @@
328 367 */
329 368 public function restore_single_image($image_id, $blog_id) {
330 369
331 370 $switched_blog = false;
332 - if (is_multisite() && current_user_can('manage_network_options')) {
371 + if (is_multisite() && WP_Optimize()->current_user_can('manage_network_options')) {
333 372 switch_to_blog($blog_id);
334 373 $switched_blog = true;
335 374 } elseif (is_multisite() && get_current_blog_id() != $blog_id) {
336 375 return new WP_Error('restore_backup_wrong_blog_id', __('The blog ID provided does not match the current blog.', 'wp-optimize'));
@@ -338,15 +377,23 @@
338 377
339 378 $error = false;
340 379
341 380 $image_path = get_attached_file($image_id);
342 - $backup_path = get_post_meta($image_id, 'original-file', true);
343 -
381 + $backup_path = get_post_meta($image_id, '_wpo-original-file', true);
382 + $uploads_dir = wp_upload_dir();
383 + $uploads_basedir = realpath($uploads_dir['basedir']);
384 +
385 + if (false === $uploads_basedir) {
386 + if ($switched_blog) {
387 + restore_current_blog();
388 + }
389 + return new WP_Error('restore_backup_issue', __('The uploads base directory is not correct.', 'wp-optimize'));
390 + }
391 +
392 + $uploads_basedir = trailingslashit($uploads_basedir);
393 +
344 394 // If the file doesn't exist, check if it's relative
345 395 if (!is_file($backup_path)) {
346 - $uploads_dir = wp_upload_dir();
347 - $uploads_basedir = trailingslashit($uploads_dir['basedir']);
348 -
349 396 if (is_file($uploads_basedir . $backup_path)) {
350 397 $backup_path = $uploads_basedir . $backup_path;
351 398 }
352 399 }
@@ -375,17 +422,27 @@
375 422 $backup_path = $uploads_basedir . $backup_path;
376 423 }
377 424 }
378 425
426 + $backup_path = realpath($backup_path);
427 + if (!$backup_path || 0 !== strpos(trailingslashit(dirname($backup_path)), $uploads_basedir)) {
428 + if ($switched_blog) {
429 + restore_current_blog();
430 + }
431 + return new WP_Error('restore_failed', __('The backup file path seems suspicious, and could not be deleted.', 'wp-optimize'));
432 + }
433 +
434 +
379 435 if (!is_file($backup_path)) {
380 436 // Delete information about backup.
381 - delete_post_meta($image_id, 'original-file');
437 + delete_post_meta($image_id, '_wpo-original-file');
382 438 $error = new WP_Error('restore_backup_not_found', __('The backup was not found; it may have been deleted or was already restored', 'wp-optimize'));
383 - } elseif (!is_writable($image_path)) {
384 - $error = new WP_Error('restore_failed', __('The destination could not be written to.', 'wp-optimize').' '.__("Please check your folder's permissions", 'wp-optimize'));
439 + } elseif (!wp_is_writable($image_path)) {
440 + $error = new WP_Error('restore_failed', __('The destination could not be written to.', 'wp-optimize').' '.__("Please check your folder's permissions", 'wp-optimize'));
385 441 } elseif (!copy($backup_path, $image_path)) {
386 - $error = new WP_Error('restore_failed', __('The file could not be copied; check your PHP error logs for details', 'wp-optimize'));
387 - } elseif (!unlink($backup_path)) {
442 + $error = new WP_Error('restore_failed', __('The file could not be copied; check your PHP error logs for details', 'wp-optimize'));
443 + } elseif (!WP_Optimize_Utils::wp_delete_file($backup_path)) {
444 + // translators: %s is the backup file path
388 445 $error = new WP_Error('restore_failed', sprintf(__('The backup file %s could not be deleted.', 'wp-optimize'), $backup_path));
389 446 }
390 447
391 448 if (!$error) {
@@ -390,12 +447,12 @@
390 447
391 448 if (!$error) {
392 449 // if backup image deleted successfully
393 450 // then delete from attachment meta associated smush data
394 - delete_post_meta($image_id, 'smush-complete');
395 - delete_post_meta($image_id, 'smush-stats');
396 - delete_post_meta($image_id, 'original-file');
397 - delete_post_meta($image_id, 'smush-info');
451 + delete_post_meta($image_id, '_wpo-smush-complete');
452 + delete_post_meta($image_id, '_wpo-smush-stats');
453 + delete_post_meta($image_id, '_wpo-original-file');
454 + delete_post_meta($image_id, '_wpo-smush-info');
398 455 }
399 456
400 457 if ($switched_blog) {
401 458 restore_current_blog();
@@ -417,9 +474,9 @@
417 474 *
418 475 * @param bool $restore_backup if true then restore images from backup otherwise just delete meta.
419 476 * @param int $blog_id blog id.
420 477 * @param int $images_limit how many images process per time.
421 - * @param bool $delete_only_backups_meta meta fields will deleted only for images those will restored from backup.
478 + * @param bool $delete_only_backups_meta meta fields will be deleted only for images those will be restored from backup.
422 479 *
423 480 * @return array ['completed' => (bool), 'message' => (string), 'error' => (string)]
424 481 */
425 482 public function bulk_restore_compressed_images($restore_backup, $blog_id = 1, $images_limit = 100, $delete_only_backups_meta = false) {
@@ -431,8 +488,9 @@
431 488
432 489 $result = array(
433 490 'completed' => false,
434 491 'message' => '',
492 + 'smushed_images_count' => 0,
435 493 );
436 494
437 495 $processed = 0;
438 496
@@ -437,9 +495,9 @@
437 495 $processed = 0;
438 496
439 497 if ($restore_backup) {
440 498 // get post ids those have backup meta field.
441 - $image_ids = $wpdb->get_results($wpdb->prepare("SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = 'original-file' LIMIT %d;", $images_limit), ARRAY_A);
499 + $image_ids = $wpdb->get_results($wpdb->prepare("SELECT post_id FROM `{$wpdb->postmeta}` WHERE meta_key = '_wpo-original-file' LIMIT %d;", $images_limit), ARRAY_A);
442 500
443 501 if (!empty($image_ids)) {
444 502 // run restore function for each found image.
445 503 foreach ($image_ids as $image) {
@@ -444,9 +502,9 @@
444 502 // run restore function for each found image.
445 503 foreach ($image_ids as $image) {
446 504 $restore_result = $this->restore_single_image($image['post_id'], $blog_id);
447 505
448 - // if we get an error then we stop the work, except situation when "backup already restored'.
506 + // if we get an error then we stop the work, except situation when "backup already restored".
449 507 if (is_wp_error($restore_result) && 'restore_backup_not_found' != $restore_result->get_error_code()) {
450 508 // we need to stop the work as we haven't restored the backup.
451 509 $result['error'] = $restore_result->get_error_message();
452 510 $this->options->delete_option('smush_images_restored');
@@ -459,9 +517,9 @@
459 517
460 518 $images_count = count($image_ids);
461 519
462 520 // if all images processed then set flag completed to true.
463 - if ($processed == $images_count && $images_count < $images_limit) {
521 + if ($processed === $images_count && $images_count < $images_limit) {
464 522 $this->options->delete_option('smush_images_restored');
465 523 $result['completed'] = true;
466 524 } else {
467 525 // save into options total processed count.
@@ -468,10 +526,12 @@
468 526 $processed += $this->options->get_option('smush_images_restored', 0);
469 527 $this->options->update_option('smush_images_restored', $processed);
470 528
471 529 if (is_multisite()) {
472 - $result['message'] = sprintf(__('%s compressed images were restored from their backup for the site %s', 'wp-optimize'), $processed, get_site_url($blog_id));
530 + // translators: %1$s is the number of restored images, %2$s is the site url.
531 + $result['message'] = sprintf(__('%1$s compressed images were restored from their backup for the site %2$s', 'wp-optimize'), $processed, get_site_url($blog_id));
473 532 } else {
533 + // translators: %s is the number of restored images.
474 534 $result['message'] = sprintf(__('%s compressed images were restored from their backup', 'wp-optimize'), $processed);
475 535 }
476 536 }
477 537
@@ -480,16 +540,35 @@
480 540 $result['completed'] = true;
481 541 }
482 542
483 543 if ($result['completed']) {
544 +
545 + $smushed_images_count = $wpdb->get_var("SELECT COUNT(*) FROM `{$wpdb->postmeta}` WHERE meta_key='_wpo-smush-complete' AND meta_value=1");
546 + $result['smushed_images_count'] = $smushed_images_count;
547 +
484 548 if ($delete_only_backups_meta) {
485 549 if (is_multisite()) {
486 - $result['message'] = sprintf(__('All the compressed images for the site %s were successfully restored.', 'wp-optimize'), get_site_url($blog_id));
550 + if ($smushed_images_count > 0) {
551 + // translators: %s is the site url
552 + $result['message'] = sprintf(__('All the compressed images for site %s with backup copies of their original files were successfully restored.', 'wp-optimize'), get_site_url($blog_id));
553 + // translators: %s is the number of images
554 + $result['message'] .= ' '.sprintf(_n('Unable to restore %s image without backup files.', 'Unable to restore %s images without backup files.', $smushed_images_count, 'wp-optimize'), $smushed_images_count);
555 + } else {
556 + // translators: %s is the site url
557 + $result['message'] = sprintf(__('All the compressed images for the site %s were successfully restored.', 'wp-optimize'), get_site_url($blog_id));
558 + }
487 559 } else {
488 - $result['message'] = __('All the compressed images were successfully restored.', 'wp-optimize');
560 + if ($smushed_images_count > 0) {
561 + $result['message'] = __('All the compressed images with backup copies of their original files were successfully restored.', 'wp-optimize');
562 + // translators: %s is the number of images
563 + $result['message'] .= ' '.sprintf(_n('Unable to restore %s image without backup files.', 'Unable to restore %s images without backup files.', $smushed_images_count, 'wp-optimize'), $smushed_images_count);
564 + } else {
565 + $result['message'] = __('All the compressed images were successfully restored.', 'wp-optimize');
566 + }
489 567 }
490 568 } else {
491 569 if (is_multisite()) {
570 + // translators: %s is the site url
492 571 $result['message'] = sprintf(__('All the compressed images for the site %s were successfully marked as uncompressed.', 'wp-optimize'), get_site_url($blog_id));
493 572 } else {
494 573 $result['message'] = __('All the compressed images were successfully marked as uncompressed.', 'wp-optimize');
495 574 }
@@ -496,11 +575,11 @@
496 575 }
497 576
498 577 // clear all metas for smushed images after work completed.
499 578 // if $delete_only_backup_meta set to true then all meta fields was deleted in restore_single_image()
500 - // and we don't need delete metas for other images.
579 + // and we don't need to delete metas for other images.
501 580 if (!$delete_only_backups_meta) {
502 - $wpdb->query("DELETE FROM {$wpdb->postmeta} WHERE meta_key IN ('smush-complete', 'smush-stats', 'original-file', 'smush-info');");
581 + $wpdb->query("DELETE FROM `{$wpdb->postmeta}` WHERE meta_key IN ('_wpo-smush-complete', '_wpo-smush-stats', '_wpo-original-file', '_wpo-smush-info');");
503 582 }
504 583 }
505 584
506 585 if (is_multisite()) {
@@ -516,9 +595,9 @@
516 595 * @param array $images - the array of images to process
517 596 * @return bool - true if processing complete
518 597 */
519 598 public function process_bulk_smush($images = array()) {
520 -
599 +
521 600 // Get a list of pending tasks so we can exclude those
522 601 $pending_tasks = $this->get_pending_tasks();
523 602 $queued_images = array();
524 603
@@ -531,28 +610,20 @@
531 610 'blog_id' => $task->get_option('blog_id')
532 611 );
533 612 }
534 613 }
535 -
614 + $default_task_options = $this->get_smush_options();
536 615 foreach ($images as $image) {
537 616 // Skip if already in the queue
538 617 if (in_array($image, $queued_images)) continue;
539 618
540 - $options = array(
541 - 'attachment_id' => intval($image['attachment_id']),
542 - 'blog_id' => intval($image['blog_id']),
543 - 'image_quality' => $this->options->get_option('image_quality', 92),
544 - 'keep_original' => $this->options->get_option('back_up_original', true),
545 - 'preserve_exif' => $this->options->get_option('preserve_exif', true),
546 - 'lossy_compression' => $this->options->get_option('lossy_compression', false)
547 - );
548 -
619 + $task_options = array_merge($default_task_options, array('attachment_id' => intval($image['attachment_id']), 'blog_id' => intval($image['blog_id'])));
549 620 $server = $this->options->get_option('compression_server', $this->webservice);
550 621 $task_name = $this->get_associated_task($server);
551 622
552 623 $blog_info = is_multisite() ? ', Blog ID : '.intval($image['blog_id']) : '';
553 - $description = "$task_name - Attachment ID : ". intval($image['attachment_id']) . $blog_info . ", Started on : ". date("F d, Y h:i:s", time());
554 - $task = call_user_func(array($task_name, 'create_task'), 'smush', $description, $options, $task_name);
624 + $description = "$task_name - Attachment ID : ". intval($image['attachment_id']) . $blog_info . ", Started on : ". gmdate("F d, Y h:i:s", time());
625 + $task = call_user_func(array($task_name, 'create_task'), 'smush', $description, $task_options, $task_name);
555 626 if ($task) $this->set_task_logger($task);
556 627 }
557 628
558 629 $this->process_smush_tasks();
@@ -605,19 +676,19 @@
605 676 */
606 677 public function record_stats($task) {
607 678
608 679 $attachment_id = $task->get_option('attachment_id');
609 - $completed_task_count = $this->options->get_option('completed_task_count', false);
680 + $completed_task_count = $this->options->get_option('completed_task_count');
610 681 $failed_task_count = $this->options->get_option('failed_task_count', 0);
611 - $total_bytes_saved = $this->options->get_option('total_bytes_saved', false);
682 + $total_bytes_saved = $this->options->get_option('total_bytes_saved');
612 683 $total_percent_saved = $this->options->get_option('total_percent_saved', 0);
613 684
614 - if ('ud_task_failed' == current_action()) {
685 + if ('ud_task_failed' === current_action()) {
615 686 $this->options->update_option('failed_task_count', ++$failed_task_count);
616 687 return;
617 688 }
618 689
619 - if (false === $completed_task_count) {
690 + if (empty($completed_task_count)) {
620 691 $completed_task_count = $total_bytes_saved = 0;
621 692 }
622 693
623 694 if (!$total_bytes_saved) {
@@ -625,12 +696,12 @@
625 696 }
626 697
627 698 if (is_multisite()) {
628 699 switch_to_blog($task->get_option('blog_id', 1));
629 - $stats = get_post_meta($attachment_id, 'smush-stats', true);
700 + $stats = get_post_meta($attachment_id, '_wpo-smush-stats', true);
630 701 restore_current_blog();
631 702 } else {
632 - $stats = get_post_meta($attachment_id, 'smush-stats', true);
703 + $stats = get_post_meta($attachment_id, '_wpo-smush-stats', true);
633 704 }
634 705
635 706 if (isset($stats['sizes-info'])) {
636 707
@@ -643,11 +714,11 @@
643 714 }
644 715
645 716 $percent = round((($original_size - $compressed_size) / $original_size * 100), 2);
646 717 } else {
647 - $original_size = isset($stats['original-size']) ? $stats['original-size'] : 0;
648 - $compressed_size = isset($stats['smushed-size']) ? $stats['smushed-size'] : 0;
649 - $percent = isset($stats['savings-percent']) ? $stats['savings-percent'] : 0;
718 + $original_size = $stats['original-size'] ?? 0;
719 + $compressed_size = $stats['smushed-size'] ?? 0;
720 + $percent = $stats['savings-percent'] ?? 0;
650 721 }
651 722
652 723 $saved = $original_size - $compressed_size;
653 724 $completed_task_count++;
@@ -670,16 +741,17 @@
670 741 if (empty($smush_options)) {
671 742 $smush_options = array(
672 743 'compression_server' => $this->options->get_option('compression_server', $this->get_default_webservice()),
673 744 'image_quality' => $this->options->get_option('image_quality', 92),
674 - 'lossy_compression' => $this->options->get_option('lossy_compression', false),
745 + 'lossy_compression' => $this->options->get_option('lossy_compression'),
746 + 'keep_original' => $this->options->get_option('back_up_original', true),//repeated below
675 747 'back_up_original' => $this->options->get_option('back_up_original', true),
676 748 'back_up_delete_after' => $this->options->get_option('back_up_delete_after', true),
677 749 'back_up_delete_after_days' => $this->options->get_option('back_up_delete_after_days', 50),
678 750 'preserve_exif' => $this->options->get_option('preserve_exif', false),
679 - 'autosmush' => $this->options->get_option('autosmush', false),
680 - 'show_smush_metabox' => $this->options->get_option('show_smush_metabox', 'show') == 'show' ? true : false,
681 - 'webp_conversion' => $this->options->get_option('webp_conversion', false)
751 + 'autosmush' => $this->options->get_option('autosmush'),
752 + 'show_smush_metabox' => $this->options->get_option('show_smush_metabox', 'show') === 'show',
753 + 'webp_conversion' => $this->options->get_option('webp_conversion')
682 754 );
683 755 }
684 756 return $smush_options;
685 757 }
@@ -684,20 +756,29 @@
684 756 return $smush_options;
685 757 }
686 758
687 759 /**
688 - * Updates global smush options
760 + * Update smush options
761 + * Only options whose values differ from the stored values are updated.
689 762 *
690 - * @param array $options - sent in via AJAX
691 - * @return bool - status of the update
763 + * @param array $options Associative array of option names and values sent in via AJAX.
764 + * @return bool True if all updates succeeded or no changes were required,
765 + * false if at least one option update failed.
692 766 */
693 767 public function update_smush_options($options) {
694 -
768 + $success = true;
695 769 foreach ($options as $option => $value) {
696 - $this->options->update_option($option, $value);
770 + // Here we only store string, array as string after serialization, boolean, and integer values which will be stored as strings (LONGTEXT field type)
771 + // So loose comparison is fine, strict comparison results to buggy behavior
772 + if ($this->options->get_option($option) == $value) {
773 + continue;
774 + }
775 +
776 + if (!$this->options->update_option($option, $value)) {
777 + $success = false;
778 + }
697 779 }
698 -
699 - return true;
780 + return $success;
700 781 }
701 782
702 783 /**
703 784 * Clears smush related stats
@@ -718,8 +799,10 @@
718 799 *
719 800 * @return array - translations used in JS
720 801 */
721 802 public function smush_js_translations() {
803 + $resmushit_article_link = WP_Optimize()->wp_optimize_url('https://resmush.it/api/', __('resmushIt', 'wp-optimize'), '', '', true);
804 +
722 805 return apply_filters('updraft_smush_js_translations', array(
723 806 'all_images_compressed' => __('No uncompressed images were found.', 'wp-optimize'),
724 807 'error_unexpected_response' => __('An unexpected response was received from the server.', 'wp-optimize') . ' ' . __('More information has been logged in the browser console.', 'wp-optimize'),
725 808 'compress_single_image_dialog' => __('Please wait: compressing the selected image.', 'wp-optimize'),
@@ -725,9 +808,14 @@
725 808 'compress_single_image_dialog' => __('Please wait: compressing the selected image.', 'wp-optimize'),
726 809 'error_try_again_later' => __('Please try again later.', 'wp-optimize'),
727 810 'server_check' => __('Connecting to the Smush API server, please wait', 'wp-optimize'),
728 811 'please_wait' => __('Please wait while the request is being processed', 'wp-optimize'),
729 - 'server_error' => __('There was an error connecting to the image compression server.', 'wp-optimize') . ' ' . __('This could mean either the server is temporarily unavailable or there are connectivity issues with your internet connection.', 'wp-optimize') . ' ' . __('Please try later.', 'wp-optimize'),
812 + 'server_error' => __('There was an error connecting to the image compression server.', 'wp-optimize') .
813 + '<br>' . __('This could mean either the server is temporarily unavailable or there are connectivity issues with your internet connection.', 'wp-optimize') . ' ' .
814 + // translators: %s is a link
815 + '<i>' . sprintf(__('(Also ensure IPs listed at the bottom of this %s page are whitelisted by your webserver).', 'wp-optimize'), $resmushit_article_link) . '</i>' .
816 + '<br>' . __('Please try later.', 'wp-optimize'),
817 + 'exceeded_max_filesize' => __('This image is too large to be optimized — it exceeds the provider\'s size limit', 'wp-optimize'),
730 818 'please_select_images' => __('Please select the images you want compressed from the "Uncompressed images" panel first', 'wp-optimize'),
731 819 'please_updating_images_info' => __('Please wait: updating information about the selected image.', 'wp-optimize'),
732 820 'please_select_compressed_images' => __('Please select the images you want to mark as already compressed from the "Uncompressed images" panel first', 'wp-optimize'),
733 821 'view_image' => __('View Image', 'wp-optimize'),
@@ -734,11 +822,17 @@
734 822 'delete_image_backup_confirm' => __('Do you really want to delete all backup images now?', 'wp-optimize') . ' ' . __('This action is irreversible.', 'wp-optimize'),
735 823 'mark_all_images_uncompressed' => __('Do you really want to mark all the images as uncompressed?', 'wp-optimize') . ' ' . __('This action is irreversible.', 'wp-optimize'),
736 824 'restore_images_from_backup' => __('Do you want to restore the original images from the backup (where they exist?)', 'wp-optimize'),
737 825 'restore_all_compressed_images' => __('Do you really want to restore all the compressed images?', 'wp-optimize'),
826 + 'webp_conversion_tool_error' => __('No WebP conversion tools are available on your web-server.', 'wp-optimize'),
827 + 'webp_conversion_tool_how_to' => __('How to get the WebP conversion tools to work?', 'wp-optimize'),
738 828 'more' => __('More', 'wp-optimize'),
739 829 'less' => __('Less', 'wp-optimize'),
740 830 'converting_to_webp' => __('Converting image to WebP format, please wait', 'wp-optimize'),
831 + 'compress_image' => __('Compress Image', 'wp-optimize'),
832 + 'compress' => __('Compress', 'wp-optimize'),
833 + 'cancel' => __('Cancel', 'wp-optimize'),
834 + 'close' => __('Close', 'wp-optimize'),
741 835 ));
742 836 }
743 837
744 838 /**
@@ -763,14 +857,14 @@
763 857 * @param WP_Post $post - a post object
764 858 */
765 859 public function render_smush_metabox($post) {
766 860
767 - $compressed = get_post_meta($post->ID, 'smush-complete', true) ? true : false;
768 - $has_backup = get_post_meta($post->ID, 'original-file', true) ? true : false;
861 + $compressed = (bool) get_post_meta($post->ID, '_wpo-smush-complete', true);
862 + $has_backup = (bool) get_post_meta($post->ID, '_wpo-original-file', true);
769 863
770 - $smush_info = get_post_meta($post->ID, 'smush-info', true);
771 - $smush_stats = get_post_meta($post->ID, 'smush-stats', true);
772 - $marked = get_post_meta($post->ID, 'smush-marked', false);
864 + $smush_info = get_post_meta($post->ID, '_wpo-smush-info', true);
865 + $smush_stats = get_post_meta($post->ID, '_wpo-smush-stats', true);
866 + $marked = get_post_meta($post->ID, '_wpo-smush-marked');
773 867
774 868 $options = Updraft_Smush_Manager()->get_smush_options();
775 869
776 870 $file = get_attached_file($post->ID);
@@ -779,18 +873,20 @@
779 873 $file_size = ($file && is_file($file)) ? filesize($file) : 0;
780 874
781 875 $extract = array(
782 876 'post_id' => $post->ID,
783 - 'smush_display' => $compressed ? "style='display:none;'" : "style='display:block;'",
784 - 'restore_display' => $compressed ? "style='display:block;'" : "style='display:none;'",
785 - 'restore_action' => $has_backup ? "style='display:block;'" : "style='display:none;'",
786 - 'smush_mark' => !$compressed && !$marked ? "style='display:block;'" : "style='display:none;'",
787 - 'smush_unmark' => $marked ? "style='display:block;'" : "style='display:none;'",
788 - 'smush_info' => $smush_info ? $smush_info : ' ',
877 + 'smush_display' => $compressed ? "display:none;" : "display:block;",
878 + 'restore_display' => $compressed ? "display:block;" : "display:none;",
879 + 'restore_action' => $has_backup ? "display:block;" : "display:none;",
880 + 'smush_mark' => !$compressed && !$marked ? "display:block;" : "display:none;",
881 + 'smush_unmark' => $marked ? "display:block;" : "display:none;",
882 + 'smush_info' => $smush_info ?: ' ',
789 883 'file_size' => $file_size,
790 884 'smush_options' => $options,
791 885 'custom' => 90 >= $options['image_quality'] && 65 <= $options['image_quality'],
792 886 'smush_details' => '',
887 + 'restore_tooltip' => $this->get_restore_image_tooltip_text(),
888 + 'smush_marked' => $marked,
793 889 );
794 890
795 891 if (!empty($smush_stats['sizes-info'])) {
796 892 $extract['smush_details'] = WP_Optimize()->include_template('images/smush-details.php', true, array('sizes_info' => $smush_stats['sizes-info']));
@@ -795,17 +891,31 @@
795 891 if (!empty($smush_stats['sizes-info'])) {
796 892 $extract['smush_details'] = WP_Optimize()->include_template('images/smush-details.php', true, array('sizes_info' => $smush_stats['sizes-info']));
797 893 }
798 894
895 + $extract['smush_settings_form'] = WP_Optimize()->include_template('admin-metabox-smush-settings.php', true, $extract);
799 896 $extract['compressed_by_another_plugin'] = $this->is_image_compressed_by_another_plugin($post->ID);
800 897 if (WPO_Image_Utils::is_supported_extension($ext, $allowed_extensions)) {
801 898 WP_Optimize()->include_template('admin-metabox-smush.php', false, $extract);
802 899 } else {
803 - printf("<p>%s</p>", __('Compressing this file type extension is not supported', 'wp-optimize'));
900 + printf("<p>%s</p>", esc_html__('Compressing this file type extension is not supported', 'wp-optimize'));
804 901 }
805 902 }
806 903
807 904 /**
905 + * Get text for restore image tooltip.
906 + *
907 + * @return string
908 + */
909 + private function get_restore_image_tooltip_text() {
910 + $text = __('Only the original image will be restored.', 'wp-optimize');
911 + $text .= ' ';
912 + $text .= __('In order to restore the other sizes, you should use a plugin such as "Regenerate Thumbnails".', 'wp-optimize');
913 +
914 + return $text;
915 + }
916 +
917 + /**
808 918 * Check if a single image compressed by another plugin.
809 919 *
810 920 * @param int $image_id
811 921 * @return bool
@@ -811,10 +921,11 @@
811 921 * @return bool
812 922 */
813 923 private function is_image_compressed_by_another_plugin($image_id) {
814 924 global $wpdb;
925 + static $is_ewwwio_images_table_exists = null;
815 926
816 - $meta = $wpdb->get_results("SELECT meta_key, meta_value FROM {$wpdb->postmeta} WHERE `post_id`={$image_id}", ARRAY_A);
927 + $meta = $wpdb->get_results($wpdb->prepare("SELECT meta_key, meta_value FROM `{$wpdb->postmeta}` WHERE `post_id`=%d", $image_id), ARRAY_A);
817 928
818 929 if (is_array($meta)) {
819 930 foreach ($meta as $row) {
820 931 // Smush, Imagify, Compress JPEG & PNG images by TinyPNG.
@@ -819,16 +930,18 @@
819 930 foreach ($meta as $row) {
820 931 // Smush, Imagify, Compress JPEG & PNG images by TinyPNG.
821 932 if (in_array($row['meta_key'], array('wp-smpro-smush-data', '_imagify_optimization_level', 'tiny_compress_images'))) return true;
822 933 // ShortPixel Image Optimizer
823 - if ('_shortpixel_status' == $row['meta_key'] && 2 <= $row['meta_key'] && 3 > $row['meta_key']) return true;
934 + if ('_shortpixel_status' === $row['meta_key'] && 2 <= (int) $row['meta_value'] && 3 > (int) $row['meta_value']) return true;
824 935 }
825 936 }
826 937
827 - if (WP_Optimize()->get_db_info()->table_exists('ewwwio_images')) {
938 + $is_ewwwio_images_table_exists = is_null($is_ewwwio_images_table_exists) ? WP_Optimize()->get_db_info()->table_exists('ewwwio_images') : $is_ewwwio_images_table_exists;
939 +
940 + if ($is_ewwwio_images_table_exists) {
828 941 $old_show_errors = $wpdb->show_errors(false);
829 942 // EWWW Image Optimizer.
830 - $ewww_image = $wpdb->get_col("SELECT attachment_id FROM {$wpdb->prefix}ewwwio_images WHERE attachment_id={$image_id} AND gallery='media' LIMIT 1");
943 + $ewww_image = $wpdb->get_col($wpdb->prepare("SELECT attachment_id FROM `{$wpdb->prefix}ewwwio_images` WHERE attachment_id=%d AND gallery='media' LIMIT 1", $image_id));
831 944 if (!empty($ewww_image)) return true;
832 945 $wpdb->show_errors($old_show_errors);
833 946 }
834 947
@@ -847,15 +960,15 @@
847 960
848 961 if (!WP_Optimize()->get_db_info()->table_exists('ewwwio_images')) return $args;
849 962
850 963 $old_show_errors = $wpdb->show_errors(false);
851 - $compressed_images = $wpdb->get_col("SELECT DISTINCT(attachment_id) FROM {$wpdb->prefix}ewwwio_images WHERE gallery='media'");
964 + $compressed_images = $wpdb->get_col("SELECT DISTINCT(attachment_id) FROM `{$wpdb->prefix}ewwwio_images` WHERE gallery='media'");
852 965 $wpdb->show_errors($old_show_errors);
853 966
854 967 if (isset($args['post__not_in'])) {
855 - $args['post__not_in'] = array_merge($args['post__not_in'], $compressed_images);
968 + $args['post__not_in'] = array_merge($args['post__not_in'], $compressed_images); // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_post__not_in -- is necessary and used with caution
856 969 } else {
857 - $args['post__not_in'] = $compressed_images;
970 + $args['post__not_in'] = $compressed_images; // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_post__not_in -- is necessary and used with caution
858 971 }
859 972
860 973 return $args;
861 974 }
@@ -862,16 +975,17 @@
862 975
863 976 /**
864 977 * Returns a list of images for smush (from cache if available)
865 978 *
979 + * @param string $use_cache
866 980 * @return array - uncompressed images
867 981 */
868 - public function get_uncompressed_images() {
869 -
870 - $uncompressed_images = $this->get_from_cache('uncompressed_images');
982 + public function get_uncompressed_images($use_cache = "true") {
983 + if ("true" === $use_cache) {
984 + $uncompressed_images = $this->get_from_cache('uncompressed_images');
985 + if ($uncompressed_images && is_array($uncompressed_images)) return $uncompressed_images;
986 + }
871 987
872 - if ($uncompressed_images) return $uncompressed_images;
873 -
874 988 $uncompressed_images = array();
875 989 $accepted_mimes = array('image/jpeg', 'image/gif', 'image/png');
876 990
877 991 $args = array(
@@ -878,61 +992,11 @@
878 992 'post_type' => 'attachment',
879 993 'post_mime_type' => $accepted_mimes,
880 994 'post_status' => 'inherit',
881 995 'posts_per_page' => apply_filters('updraft_smush_posts_per_page', 1000),
882 - 'meta_query' => array(
883 - 'relation' => 'AND',
884 - array(
885 - 'relation' => 'OR',
886 - array(
887 - 'key' => 'smush-complete',
888 - 'compare' => '!=',
889 - 'value' => '1',
890 - ),
891 - array(
892 - 'key' => 'smush-complete',
893 - 'compare' => 'NOT EXISTS',
894 - 'value' => '',
895 - ),
896 - ),
897 - // ShortPixel Image Optimizer plugin
898 - array(
899 - 'relation' => 'OR',
900 - array(
901 - 'key' => '_shortpixel_status',
902 - 'compare' => '<',
903 - 'value' => '2',
904 - ),
905 - array(
906 - 'key' => '_shortpixel_status',
907 - 'compare' => '>=',
908 - 'value' => '3',
909 - ),
910 - array(
911 - 'key' => '_shortpixel_status',
912 - 'compare' => 'NOT EXISTS',
913 - 'value' => '',
914 - ),
915 - ),
916 - // Smush plugin
917 - array(
918 - 'key' => 'wp-smpro-smush-data',
919 - 'compare' => 'NOT EXISTS',
920 - 'value' => '',
921 - ),
922 - // Imagify
923 - array(
924 - 'key' => '_imagify_optimization_level',
925 - 'compare' => 'NOT EXISTS',
926 - 'value' => '',
927 - ),
928 - // Compress JPEG & PNG images by TinyPNG
929 - array(
930 - 'key' => 'tiny_compress_images',
931 - 'compare' => 'NOT EXISTS',
932 - 'value' => '',
933 - ),
934 - )
996 + 'meta_query' => $this->get_uncompressed_images_meta_query(),
997 + 'no_found_rows' => true,
998 + 'fields' => 'ids'
935 999 );
936 1000
937 1001 $allowed_extensions = WPO_Image_Utils::get_allowed_extensions();
938 1002
@@ -947,22 +1011,25 @@
947 1011 $args = apply_filters('wpo_get_uncompressed_images_args', $args);
948 1012 $images = new WP_Query($args);
949 1013
950 1014 foreach ($images->posts as $image) {
951 - $file = get_attached_file($image->ID);
1015 + // If `field` is removed from $args it returns a WP_Post obj
1016 + $image_id = is_int($image) ? $image : $image->ID;
1017 +
1018 + $file = get_attached_file($image_id);
952 1019 $ext = WPO_Image_Utils::get_extension($file);
953 1020 if (file_exists($file)) {
954 1021 if (WPO_Image_Utils::is_supported_extension($ext, $allowed_extensions)) {
955 1022 $uncompressed_images[$site->blog_id][] = array(
956 - 'id' => $image->ID,
957 - 'thumb_url' => wp_get_attachment_thumb_url($image->ID),
958 - 'filesize' => filesize(get_attached_file($image->ID))
1023 + 'id' => $image_id,
1024 + 'thumb_url' => wp_get_attachment_thumb_url($image_id),
1025 + 'filesize' => filesize(get_attached_file($image_id))
959 1026 );
960 1027 } else {
961 - $this->log("Blog_id={$site->blog_id}, ID={$image->ID}, File={$file} This image type is not supported.");
1028 + $this->log("Blog_id=$site->blog_id, ID=$image_id, File=$file This image type is not supported.");
962 1029 }
963 1030 } else {
964 - $this->log("Could not find file for image: blog_id={$site->blog_id}, ID={$image->ID}, file={$file}");
1031 + $this->log("Could not find file for image: blog_id=$site->blog_id, ID=$image_id, file=$file");
965 1032 }
966 1033 }
967 1034
968 1035 restore_current_blog();
@@ -971,23 +1038,26 @@
971 1038 } else {
972 1039 $args = apply_filters('wpo_get_uncompressed_images_args', $args);
973 1040 $images = new WP_Query($args);
974 1041 foreach ($images->posts as $image) {
975 - $file = get_attached_file($image->ID);
1042 + // If `field` is removed from $args it returns a WP_Post obj
1043 + $image_id = is_int($image) ? $image : $image->ID;
1044 +
1045 + $file = get_attached_file($image_id);
976 1046 $ext = WPO_Image_Utils::get_extension($file);
977 1047
978 1048 if (file_exists($file)) {
979 1049 if (WPO_Image_Utils::is_supported_extension($ext, $allowed_extensions)) {
980 1050 $uncompressed_images[1][] = array(
981 - 'id' => $image->ID,
982 - 'thumb_url' => wp_get_attachment_thumb_url($image->ID),
983 - 'filesize' => filesize(get_attached_file($image->ID))
1051 + 'id' => $image_id,
1052 + 'thumb_url' => wp_get_attachment_thumb_url($image_id),
1053 + 'filesize' => filesize(get_attached_file($image_id))
984 1054 );
985 1055 } else {
986 - $this->log("Image ID={$image->ID}, File={$file} This image type is not supported.");
1056 + $this->log("Image ID=$image_id, File=$file This image type is not supported.");
987 1057 }
988 1058 } else {
989 - $this->log("Could not find file for image: ID={$image->ID}, file={$file}");
1059 + $this->log("Could not find file for image: ID=$image_id, file=$file");
990 1060 }
991 1061 }
992 1062 }
993 1063
@@ -1062,13 +1132,13 @@
1062 1132 $stats = array();
1063 1133
1064 1134 foreach ($images as $image) {
1065 1135 if (is_multisite()) {
1066 - switch_to_blog($image['blog_id'], 1);
1067 - $stats[] = get_post_meta($image['attachment_id'], 'smush-complete', true) ? 'success' : 'fail';
1136 + switch_to_blog($image['blog_id']);
1137 + $stats[] = get_post_meta($image['attachment_id'], '_wpo-smush-complete', true) ? 'success' : 'fail';
1068 1138 restore_current_blog();
1069 1139 } else {
1070 - $stats[] = get_post_meta($image['attachment_id'], 'smush-complete', true) ? 'success' : 'fail';
1140 + $stats[] = get_post_meta($image['attachment_id'], '_wpo-smush-complete', true) ? 'success' : 'fail';
1071 1141 }
1072 1142 }
1073 1143
1074 1144 return array_count_values($stats);
@@ -1076,9 +1146,9 @@
1076 1146
1077 1147 /**
1078 1148 * Returns a list of images for smush (from cache if available)
1079 1149 *
1080 - * @return array - List of task objects with uncompressed images
1150 + * @return array|mixed - List of task objects with uncompressed images
1081 1151 */
1082 1152 public function get_pending_tasks() {
1083 1153 return $this->get_active_tasks('smush');
1084 1154 }
@@ -1084,16 +1154,20 @@
1084 1154 }
1085 1155
1086 1156 /**
1087 1157 * Deletes and removes any pending tasks from queue
1158 + *
1159 + * @return bool
1088 1160 */
1089 1161 public function clear_pending_images() {
1090 1162
1091 1163 $pending_tasks = $this->get_active_tasks('smush');
1092 1164
1093 - foreach ($pending_tasks as $task) {
1094 - $task->delete_meta();
1095 - $task->delete();
1165 + if (!empty($pending_tasks)) {
1166 + foreach ($pending_tasks as $task) {
1167 + $task->delete_meta();
1168 + $task->delete();
1169 + }
1096 1170 }
1097 1171
1098 1172 return true;
1099 1173 }
@@ -1112,23 +1186,37 @@
1112 1186 * Adds the required scripts and styles
1113 1187 */
1114 1188 public function admin_enqueue_scripts() {
1115 1189 $current_screen = get_current_screen();
1116 - // load scripts and styles only on WP-Optimize pages or if show_smush_metabox option enabled.
1117 - if (!preg_match('/wp\-optimize|attachment|upload/i', $current_screen->id) && 'show' != $this->options->get_option('show_smush_metabox', 'show')) return;
1190 + if (null === $current_screen) return;
1191 + // load scripts and styles only on WP-Optimize pages
1192 + if (!preg_match('/wp\-optimize|attachment|upload/i', $current_screen->id)) return;
1118 1193
1119 1194 $enqueue_version = WP_Optimize()->get_enqueue_version();
1120 1195 $min_or_not = WP_Optimize()->get_min_or_not_string();
1121 1196 $min_or_not_internal = WP_Optimize()->get_min_or_not_internal_string();
1122 -
1197 +
1123 1198 $js_variables = $this->smush_js_translations();
1124 1199 $js_variables['ajaxurl'] = admin_url('admin-ajax.php');
1125 1200 $js_variables['features'] = $this->get_features();
1126 1201
1127 1202 $js_variables['smush_ajax_nonce'] = wp_create_nonce('updraft-task-manager-ajax-nonce');
1203 + $js_variables['smush_settings'] = $this->get_smush_options();
1204 + $js_variables['blog_id'] = get_current_blog_id();
1205 + $js_variables['compress'] = esc_html__('Compress', 'wp-optimize');
1206 + $js_variables['cancel'] = esc_html__('Cancel', 'wp-optimize');
1207 + $js_variables['cancelling'] = esc_html__('Cancelling...', 'wp-optimize');
1208 + $js_variables['images_restored_successfully'] = esc_html__('The images were restored successfully', 'wp-optimize');
1209 + $js_variables['logo_src'] = esc_url(WPO_PLUGIN_URL.'images/notices/wp_optimize_logo.png');
1128 1210
1129 1211 wp_enqueue_script('block-ui-js', WPO_PLUGIN_URL.'includes/blockui/jquery.blockUI'.$min_or_not.'.js', array('jquery'), $enqueue_version);
1130 - wp_enqueue_script('smush-js', WPO_PLUGIN_URL.'js/wposmush'.$min_or_not_internal.'.js', array('jquery', 'block-ui-js', 'wp-optimize-send-command'), $enqueue_version);
1212 + wp_enqueue_script('wp-optimize-heartbeat-js', WPO_PLUGIN_URL.'js/heartbeat'.$min_or_not_internal.'.js', array('jquery'), $enqueue_version);
1213 + wp_localize_script('wp-optimize-heartbeat-js', 'wpo_heartbeat_ajax', array(
1214 + 'ajaxurl' => admin_url('admin-ajax.php'),
1215 + 'nonce' => wp_create_nonce('heartbeat-nonce'),
1216 + 'interval' => WPO_Ajax::HEARTBEAT_INTERVAL
1217 + ));
1218 + wp_enqueue_script('smush-js', WPO_PLUGIN_URL.'js/wposmush'.$min_or_not_internal.'.js', array('jquery', 'block-ui-js', 'wp-optimize-block-ui', 'wp-optimize-send-command', 'wp-optimize-heartbeat-js'), $enqueue_version);
1131 1219 wp_enqueue_style('smush-css', WPO_PLUGIN_URL.'css/smush'.$min_or_not_internal.'.css', array(), $enqueue_version);
1132 1220 wp_localize_script('smush-js', 'wposmush', $js_variables);
1133 1221 }
1134 1222
@@ -1179,9 +1267,9 @@
1179 1267
1180 1268 /**
1181 1269 * Gets allowed service providers for smush
1182 1270 *
1183 - * @return array - key value pair of service name => task name
1271 + * @return array - A pair of key/value. e.g. service name => task name
1184 1272 */
1185 1273 public function get_allowed_services() {
1186 1274 return array(
1187 1275 'resmushit' => 'Re_Smush_It_Task',
@@ -1188,11 +1276,32 @@
1188 1276 );
1189 1277 }
1190 1278
1191 1279 /**
1280 + * Gets current compression server hint.
1281 + *
1282 + * @return string
1283 + */
1284 + public function get_compression_server_hint() {
1285 +
1286 + switch ($this->webservice) {
1287 + case 'resmushit':
1288 + $title = 'reSmush.it';
1289 + break;
1290 + default:
1291 + $title = $this->webservice;
1292 + }
1293 +
1294 + // translators: %s is a service used to compress images
1295 + $hint = sprintf(__('Service is provided by %s', 'wp-optimize'), $title);
1296 +
1297 + return $hint;
1298 + }
1299 +
1300 + /**
1192 1301 * Gets allowed service provider features smush
1193 1302 *
1194 - * @return array - key value pair of service name => features exposed
1303 + * @return array - A pair of key/value. e.g. service name => features exposed
1195 1304 */
1196 1305 public function get_features() {
1197 1306 $features = array();
1198 1307 foreach ($this->get_allowed_services() as $service => $class_name) {
@@ -1206,34 +1315,24 @@
1206 1315 *
1207 1316 * @return string - file path
1208 1317 */
1209 1318 public function get_logfile_path() {
1210 - $upload_dir = wp_upload_dir();
1211 - $upload_base = $upload_dir['basedir'];
1212 - return $upload_base . '/smush-' . substr(md5(wp_salt()), 0, 20) . '.log';
1319 + return WP_Optimize_Utils::get_log_file_path('smush');
1213 1320 }
1214 1321
1215 1322 /**
1216 1323 * Delete all smush log files
1324 + *
1325 + * @deprecated 3.5.0
1217 1326 */
1218 1327 public function delete_log_files() {
1219 - if (!function_exists('glob')) return;
1220 - $upload_dir = wp_get_upload_dir();
1221 - $upload_base = $upload_dir['basedir'];
1222 - $files = glob($upload_base . '/smush-*.log');
1223 - if (false === $files) return;
1224 - foreach ($files as $file) {
1225 - if (is_file($file)) {
1226 - @unlink($file); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- suppress error due to file permission issues
1227 - }
1228 - }
1229 -
1328 + _deprecated_function(__METHOD__, '3.5.0');
1230 1329 }
1231 1330
1232 1331 /**
1233 1332 * Adds a logger to the task
1234 1333 *
1235 - * @param Mixed $task - a task object
1334 + * @param mixed $task - a task object
1236 1335 */
1237 1336 public function set_task_logger($task) {
1238 1337 if (!$this->logger) {
1239 1338 $this->logger = new Updraft_File_Logger($this->get_logfile_path());
@@ -1266,9 +1365,9 @@
1266 1365 $log_header = array();
1267 1366
1268 1367 // phpcs:enable
1269 1368 $log_header[] = "\n";
1270 - $log_header[] = "Header for logs at time: ".date('r')." on ".network_site_url();
1369 + $log_header[] = "Header for logs at time: ".gmdate('r')." on ".network_site_url();
1271 1370 $log_header[] = "WP: ".$wp_version;
1272 1371 $php_uname = '';
1273 1372 if (function_exists('php_uname')) {
1274 1373 $php_uname = ", " . php_uname();
@@ -1275,9 +1374,9 @@
1275 1374 }
1276 1375 $log_header[] = "PHP: ".phpversion()." (".PHP_SAPI.$php_uname.")";
1277 1376 $log_header[] = "MySQL: $mysql_version";
1278 1377 $log_header[] = "WPLANG: ".get_locale();
1279 - $log_header[] = "Server: ".$_SERVER["SERVER_SOFTWARE"];
1378 + $log_header[] = "Server: ". TeamUpdraft\WP_Optimize\Includes\Fragments\fetch_superglobal('server', 'SERVER_SOFTWARE', 'string', 'sanitize_text_field', '-');
1280 1379 $log_header[] = "Outbound connections: ".(defined('WP_HTTP_BLOCK_EXTERNAL') ? 'Y' : 'N');
1281 1380 $log_header[] = "Disabled Functions: $disabled_functions";
1282 1381 $log_header[] = "max_execution_time: $max_execution_time";
1283 1382 $log_header[] = "memory_limit: $memory_limit (used: {$memory_usage}M | {$total_memory_usage}M)";
@@ -1289,12 +1388,12 @@
1289 1388 $this->log($log_entry);
1290 1389 }
1291 1390 }
1292 1391
1293 - $memlim = $this->memory_check_current();
1392 + $memory_limit = $this->memory_check_current();
1294 1393
1295 - if ($memlim<65 && $memlim>0) {
1296 - $this->log(sprintf('The amount of memory (RAM) allowed for PHP is very low (%s Mb) - you should increase it to avoid failures due to insufficient memory (consult your web hosting company for more help)', round($memlim, 1)), 'warning');
1394 + if ($memory_limit<65 && $memory_limit>0) {
1395 + $this->log(sprintf('The amount of memory (RAM) allowed for PHP is very low (%s Mb) - you should increase it to avoid failures due to insufficient memory (consult your web hosting company for more help)', round($memory_limit, 1)), 'warning');
1297 1396 }
1298 1397
1299 1398 if ($max_execution_time>0 && $max_execution_time<20) {
1300 1399 $this->log(sprintf('The amount of time allowed for WordPress plugins to run is very low (%s seconds) - you should increase it to avoid failures due to time-outs (consult your web hosting company for more help - it is the max_execution_time PHP setting; the recommended value is %s seconds or more)', $max_execution_time, 90), 'warning');
@@ -1311,9 +1410,9 @@
1311 1410
1312 1411 /**
1313 1412 * Get the WordPress version
1314 1413 *
1315 - * @return String - the version
1414 + * @return string - the version
1316 1415 */
1317 1416 public function get_wordpress_version() {
1318 1417 static $got_wp_version = false;
1319 1418
@@ -1318,9 +1417,9 @@
1318 1417 static $got_wp_version = false;
1319 1418
1320 1419 if (!$got_wp_version) {
1321 1420 global $wp_version;
1322 - @include(ABSPATH.WPINC.'/version.php');// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- suppress warning if `version.php` does not exists
1421 + @include(ABSPATH.WPINC.'/version.php');// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- suppress warning if `version.php` does not exist
1323 1422 $got_wp_version = $wp_version;
1324 1423 }
1325 1424
1326 1425 return $got_wp_version;
@@ -1328,16 +1427,18 @@
1328 1427
1329 1428 /**
1330 1429 * Get the current memory limit
1331 1430 *
1332 - * @return String - memory limit in megabytes
1431 + * @param ?string $memory_limit Memory limit in megabytes
1432 + *
1433 + * @return string - memory limit in megabytes
1333 1434 */
1334 - public function memory_check_current($memory_limit = false) {
1435 + public function memory_check_current($memory_limit = null) {
1335 1436 // Returns in megabytes
1336 - if (false == $memory_limit) $memory_limit = ini_get('memory_limit');
1437 + if (empty($memory_limit)) $memory_limit = ini_get('memory_limit');
1337 1438 $memory_limit = rtrim($memory_limit);
1338 1439 $memory_unit = $memory_limit[strlen($memory_limit)-1];
1339 - if (0 == (int) $memory_unit && '0' !== $memory_unit) {
1440 + if (0 === (int) $memory_unit && '0' !== $memory_unit) {
1340 1441 $memory_limit = substr($memory_limit, 0, strlen($memory_limit)-1);
1341 1442 } else {
1342 1443 $memory_unit = '';
1343 1444 }
@@ -1369,9 +1470,9 @@
1369 1470 public function save_to_cache($key, $value, $blog_id = 1) {
1370 1471 $transient_limit = 3600 * 48;
1371 1472 $key = 'wpo_smush_cache_' . $blog_id . '_'. $key;
1372 1473
1373 - return WP_Optimize_Transients_Cache::get_instance()->set($key, $value, $transient_limit);
1474 + WP_Optimize_Transients_Cache::get_instance()->set_transient($key, $value, $transient_limit);
1374 1475 }
1375 1476
1376 1477 /**
1377 1478 * Gets value from the cache.
@@ -1382,11 +1483,9 @@
1382 1483 */
1383 1484 public function get_from_cache($key, $blog_id = 1) {
1384 1485 $key = 'wpo_smush_cache_' . $blog_id . '_'. $key;
1385 1486
1386 - $value = WP_Optimize_Transients_Cache::get_instance()->get($key);
1387 -
1388 - return $value;
1487 + return WP_Optimize_Transients_Cache::get_instance()->get($key);
1389 1488 }
1390 1489
1391 1490 /**
1392 1491 * Deletes a value from the cache.
@@ -1422,11 +1521,11 @@
1422 1521 global $wpdb;
1423 1522
1424 1523 // get list of cached data by optimization.
1425 1524 if ($this->is_multisite_mode()) {
1426 - $keys = $wpdb->get_col("SELECT meta_key FROM {$wpdb->sitemeta} WHERE meta_key LIKE '%wpo_smush_cache_%'");
1525 + $keys = $wpdb->get_col("SELECT meta_key FROM `{$wpdb->sitemeta}` WHERE meta_key LIKE '%wpo_smush_cache_%'");
1427 1526 } else {
1428 - $keys = $wpdb->get_col("SELECT option_name FROM {$wpdb->options} WHERE option_name LIKE '%wpo_smush_cache_%'");
1527 + $keys = $wpdb->get_col("SELECT option_name FROM `{$wpdb->options}` WHERE option_name LIKE '%wpo_smush_cache_%'");
1429 1528 }
1430 1529
1431 1530 if (!empty($keys)) {
1432 1531 $transient_keys = array();
@@ -1466,19 +1565,19 @@
1466 1565 $year = (int) $match[1];
1467 1566 $month = (int) $match[2];
1468 1567
1469 1568 $limit = strtotime('-'.$days_ago.' '.(($days_ago > 1) ? 'days' : 'day'));
1470 - $year_limit = (int) date('Y', $limit);
1471 - $month_limit = (int) date('m', $limit);
1472 - $day_limit = (int) date('j', $limit);
1569 + $year_limit = (int) gmdate('Y', $limit);
1570 + $month_limit = (int) gmdate('m', $limit);
1571 + $day_limit = (int) gmdate('j', $limit);
1473 1572
1474 1573 // if current directory is newer than needed then we skip it.
1475 - if ($year_limit < $year || ($year_limit == $year && $month_limit < $month)) {
1574 + if ($year_limit < $year || ($year_limit === $year && $month_limit < $month)) {
1476 1575 return;
1477 1576 }
1478 1577
1479 1578 // we will check dates only in directory that contain limit date.
1480 - $check_date = ($year_limit == $year && $month_limit == $month);
1579 + $check_date = ($year_limit === $year && $month_limit === $month);
1481 1580 }
1482 1581
1483 1582 // GLOB_BRACE isn't defined on some systems (Solaris, SunOS and more) > https://www.php.net/manual/en/function.glob.php
1484 1583 $files = glob($directory . '*-updraft-pre-smush-original.*', (defined('GLOB_BRACE') ? GLOB_BRACE : 0));
@@ -1484,13 +1583,13 @@
1484 1583 $files = glob($directory . '*-updraft-pre-smush-original.*', (defined('GLOB_BRACE') ? GLOB_BRACE : 0));
1485 1584
1486 1585 foreach ($files as $file) {
1487 1586 if ($check_date) {
1488 - $filedate_day = (int) date('j', filectime($file));
1587 + $filedate_day = (int) gmdate('j', filectime($file));
1489 1588 if ($filedate_day >= $day_limit) continue;
1490 1589 }
1491 1590
1492 - unlink($file);
1591 + wp_delete_file($file);
1493 1592 }
1494 1593
1495 1594 } else {
1496 1595 // scan directories recursively.
@@ -1501,9 +1600,9 @@
1501 1600 $file = readdir($handle);
1502 1601
1503 1602 while (false !== $file) {
1504 1603
1505 - if ('.' == $file || '..' == $file) {
1604 + if ('.' === $file || '..' === $file) {
1506 1605 $file = readdir($handle);
1507 1606 continue;
1508 1607 }
1509 1608
@@ -1511,9 +1610,9 @@
1511 1610 $this->clear_backup_images_directory($directory . $file, $days_ago);
1512 1611 } elseif (is_file($directory . $file) && preg_match('/^.+-updraft-pre-smush-original\.\S{3,4}/i', $file)) {
1513 1612 // check the file time and compare with $days_ago.
1514 1613 $filedate_day = (int) filectime($directory . $file);
1515 - if ($filedate_day > 0 && ($current_time - $filedate_day) / 86400 >= $days_ago) unlink($directory . $file);
1614 + if ($filedate_day > 0 && ($current_time - $filedate_day) / 86400 >= $days_ago) wp_delete_file($directory . $file);
1516 1615 }
1517 1616
1518 1617 $file = readdir($handle);
1519 1618 }
@@ -1524,9 +1623,9 @@
1524 1623 /**
1525 1624 * Clean backup smush images according to saved options.
1526 1625 */
1527 1626 public function clear_backup_images() {
1528 - $back_up_delete_after = $this->options->get_option('back_up_delete_after', false);
1627 + $back_up_delete_after = $this->options->get_option('back_up_delete_after');
1529 1628
1530 1629 if (!$back_up_delete_after) return;
1531 1630
1532 1631 $back_up_delete_after_days = $this->options->get_option('back_up_delete_after_days', 50);
@@ -1544,48 +1643,12 @@
1544 1643 *
1545 1644 * @return bool
1546 1645 */
1547 1646 public function is_compressed($attachment_id) {
1548 - return (true == get_post_meta($attachment_id, 'smush-complete', true));
1647 + return (true === (bool) get_post_meta($attachment_id, '_wpo-smush-complete', true));
1549 1648 }
1550 1649
1551 1650 /**
1552 - * @param array $form_fields
1553 - * @param WP_Post $post
1554 - *
1555 - * @return array
1556 - */
1557 - public function add_compress_button_to_media_modal($form_fields, $post) {
1558 -
1559 - if (!is_admin() || !function_exists('get_current_screen')) return $form_fields;
1560 -
1561 - /**
1562 - * In media modal get_current_screen() return null or id = 'async-upload' We don't need add smush fields elsewhere.
1563 - */
1564 - $current_screen = get_current_screen();
1565 - if (null !== $current_screen && 'async-upload' != $current_screen->id) return $form_fields;
1566 -
1567 - /**
1568 - * Don't show additional fields for non-image attachments.
1569 - */
1570 - if (!wp_attachment_is_image($post->ID)) return $form_fields;
1571 -
1572 - ob_start();
1573 - $this->render_smush_metabox($post);
1574 - $smush_metabox = ob_get_contents();
1575 - ob_end_clean();
1576 -
1577 - $form_fields['wpo_compress_image'] = array(
1578 - 'value' => '',
1579 - 'label' => __('Compress image', 'wp-optimize'),
1580 - 'input' => 'html',
1581 - 'html' => $smush_metabox,
1582 - );
1583 -
1584 - return $form_fields;
1585 - }
1586 -
1587 - /**
1588 1651 * Returns true if multisite
1589 1652 *
1590 1653 * @return bool
1591 1654 */
@@ -1598,17 +1661,37 @@
1598 1661 *
1599 1662 * @param int $post_id - WordPress Post ID
1600 1663 */
1601 1664 public function unscheduled_original_file_deletion($post_id) {
1602 - $the_original_file = get_post_meta($post_id, 'original-file', true);
1665 + $the_original_file = get_post_meta($post_id, '_wpo-original-file', true);
1666 + // If no original file meta exists, there is nothing to delete.
1667 + if (empty($the_original_file)) {
1668 + return;
1669 + }
1603 1670 $uploads_dir = wp_get_upload_dir();
1604 - $the_original_file = trailingslashit($uploads_dir['basedir']) . $the_original_file;
1605 - if ('' != $the_original_file && file_exists($the_original_file)) {
1606 - @unlink($the_original_file);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- suppress warning because of file permission issues
1671 + $uploads_basedir = realpath($uploads_dir['basedir']);
1672 + if (!$uploads_basedir) return;
1673 + $uploads_basedir = trailingslashit($uploads_basedir);
1674 + $the_original_file = realpath($uploads_basedir . $the_original_file);
1675 + if ($the_original_file && 0 === strpos($the_original_file, $uploads_basedir) && file_exists($the_original_file)) {
1676 + wp_delete_file($the_original_file);
1607 1677 }
1608 1678 }
1609 1679
1610 1680 /**
1681 + * Remove failed smush tasks from the wp_tm_tasks table
1682 + */
1683 + public function clear_failed_tasks() {
1684 + $failed_tasks = $this->get_tasks('failed', 'smush');
1685 + if (empty($failed_tasks)) return;
1686 +
1687 + foreach ($failed_tasks as $task) {
1688 + $task->delete_meta();
1689 + $task->delete();
1690 + }
1691 + }
1692 +
1693 + /**
1611 1694 * Instance of WP_Optimize_Page_Cache_Preloader.
1612 1695 *
1613 1696 * @return self
1614 1697 */
@@ -1618,12 +1701,73 @@
1618 1701 }
1619 1702
1620 1703 return self::$_instance;
1621 1704 }
1705 +
1706 + /**
1707 + * Meta query array for getting uncompressed images
1708 + *
1709 + * @return array
1710 + */
1711 + public function get_uncompressed_images_meta_query() {
1712 + return array(
1713 + 'relation' => 'AND',
1714 + array(
1715 + 'relation' => 'OR',
1716 + array(
1717 + 'key' => '_wpo-smush-complete',
1718 + 'compare' => '!=',
1719 + 'value' => '1',
1720 + ),
1721 + array(
1722 + 'key' => '_wpo-smush-complete',
1723 + 'compare' => 'NOT EXISTS',
1724 + 'value' => '',
1725 + ),
1726 + ),
1727 + // ShortPixel Image Optimizer plugin
1728 + array(
1729 + 'relation' => 'OR',
1730 + array(
1731 + 'key' => '_shortpixel_status',
1732 + 'compare' => '<',
1733 + 'value' => '2',
1734 + ),
1735 + array(
1736 + 'key' => '_shortpixel_status',
1737 + 'compare' => '>=',
1738 + 'value' => '3',
1739 + ),
1740 + array(
1741 + 'key' => '_shortpixel_status',
1742 + 'compare' => 'NOT EXISTS',
1743 + 'value' => '',
1744 + ),
1745 + ),
1746 + // Smush plugin
1747 + array(
1748 + 'key' => 'wp-smpro-smush-data',
1749 + 'compare' => 'NOT EXISTS',
1750 + 'value' => '',
1751 + ),
1752 + // Imagify
1753 + array(
1754 + 'key' => '_imagify_optimization_level',
1755 + 'compare' => 'NOT EXISTS',
1756 + 'value' => '',
1757 + ),
1758 + // Compress JPEG & PNG images by TinyPNG
1759 + array(
1760 + 'key' => 'tiny_compress_images',
1761 + 'compare' => 'NOT EXISTS',
1762 + 'value' => '',
1763 + ),
1764 + );
1765 + }
1622 1766 }
1623 1767
1624 1768 /**
1625 - * Returns a Updraft_Smush_Manager instance
1769 + * Returns Updraft_Smush_Manager instance
1626 1770 */
1627 1771 function Updraft_Smush_Manager() {
1628 1772 return Updraft_Smush_Manager::instance();
1629 1773 }