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 +297 -228 3.4.2 → 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');
@@ -112,9 +111,9 @@
112 111 /**
113 112 * Add custom column to Media Library.
114 113 *
115 114 * @param array $columns
116 - * @return mixed
115 + * @return array
117 116 */
118 117 public function manage_media_columns($columns) {
119 118 $columns['wpo_smush'] = 'WP-Optimize';
120 119
@@ -139,47 +138,77 @@
139 138 *
140 139 * @return string smush details
141 140 */
142 141 public function get_smush_details($attachment_id) {
143 - $info = '';
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>';
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) {
144 157 $file = get_attached_file($attachment_id);
158 + if (false === $file) {
159 + return '';
160 + }
145 161 $ext = WPO_Image_Utils::get_extension($file);
146 162 $allowed_extensions = WPO_Image_Utils::get_allowed_extensions();
147 -
148 - $smush_stats = get_post_meta($attachment_id, 'smush-stats', true);
149 -
150 - if (empty($smush_stats)) {
151 - if ($this->is_compressed($attachment_id)) {
152 - $info = esc_html__('The file was either compressed using another tool or marked as compressed', 'wp-optimize');
153 - } else {
154 - if (in_array($ext, $allowed_extensions) && file_exists($file)) {
155 - $info = sprintf('<a href="%1$s">%2$s</a><br>', esc_url(admin_url("post.php?post=" . (int) $attachment_id . "&action=edit")), esc_html__('Compress', 'wp-optimize'));
156 - }
157 - }
158 - return $info;
163 +
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;
166 +
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']));
159 188 }
160 -
189 +
190 + $extract['compressed_by_another_plugin'] = $this->is_image_compressed_by_another_plugin($attachment_id);
191 +
192 + $output = '';
193 +
194 + if (WPO_Image_Utils::is_supported_extension($ext, $allowed_extensions)) {
195 + $output .= WP_Optimize()->include_template('admin-medialibrary-smush-column.php', true, $extract);
196 + } else {
197 + $message = __('Compressing this file type extension is not supported', 'wp-optimize');
198 + $output .= sprintf("<p>%s</p>", esc_html($message));
199 +
200 + }
201 +
161 202 if (WPO_Image_Utils::is_supported_extension($ext, array_diff($allowed_extensions, array('gif'))) && file_exists($file) && !file_exists($file . '.webp')) {
162 203 if (WPO_WebP_Utils::can_do_webp_conversion()) {
163 - $info = sprintf('<a href="#" class="convert-to-webp" data-attachment-id="%d">%s</a><br>', esc_attr($attachment_id), esc_html__('Convert to WebP', 'wp-optimize'));
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));
164 207 }
165 208 }
166 -
167 - $original_size = $smush_stats['original-size'];
168 - $smushed_size = $smush_stats['smushed-size'];
169 -
170 - if (0 == $original_size) {
171 - $info .= sprintf(esc_html__('The file was compressed to %s using WP-Optimize', 'wp-optimize'), WP_Optimize()->format_size($smushed_size));
172 - } else {
173 - $saved = round((($original_size - $smushed_size) / $original_size * 100), 2);
174 - $info .= sprintf(esc_html__('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);
175 - }
176 -
177 - // Display additional information about resized images.
178 - if (!empty($smush_stats['sizes-info'])) {
179 - $info .= WP_Optimize()->include_template('images/smush-details.php', true, array('sizes_info' => $smush_stats['sizes-info']));
180 - }
181 - return $info;
209 +
210 + return $output;
182 211 }
183 212
184 213 /**
185 214 * The Task Manager AJAX handler
@@ -185,25 +214,25 @@
185 214 * The Task Manager AJAX handler
186 215 */
187 216 public function updraft_smush_ajax() {
188 217
189 - $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');
190 221
191 - if (!wp_verify_nonce($nonce, 'updraft-task-manager-ajax-nonce') || empty($_REQUEST['subaction']))
222 + if (empty($nonce) || empty($subaction)) {
192 223 die('Security check failed');
224 + }
193 225
194 - if (!current_user_can(WP_Optimize()->capability_required())) {
226 + if (!WP_Optimize()->current_user_can()) {
195 227 die('You are not allowed to run this command.');
196 228 }
197 229
198 - $subaction = $_REQUEST['subaction'];
199 -
200 230 $allowed_commands = Updraft_Smush_Manager_Commands::get_allowed_ajax_commands();
201 231
202 232 if (in_array($subaction, $allowed_commands)) {
203 233
204 - if (isset($_REQUEST['data'])) {
205 - $data = $_REQUEST['data'];
234 + if ($data) {
206 235 $results = call_user_func(array($this->commands, $subaction), $data);
207 236 } else {
208 237 $results = call_user_func(array($this->commands, $subaction));
209 238 }
@@ -217,11 +246,11 @@
217 246 'error_data' => $results->get_error_data(),
218 247 );
219 248 }
220 249
221 - echo json_encode($results);
250 + echo wp_json_encode($results);
222 251 } else {
223 - echo json_encode(array('error' => 'No such command found'));
252 + echo wp_json_encode(array('error' => 'No such command found'));
224 253 }
225 254 die();
226 255 }
227 256
@@ -238,28 +267,22 @@
238 267 $allowed_extensions = WPO_Image_Utils::get_allowed_extensions();
239 268
240 269 if(!in_array($ext, $allowed_extensions)) return;
241 270
242 - if (!$this->options->get_option('autosmush', false))
271 + if (!$this->options->get_option('autosmush'))
243 272 return;
244 273
245 - if (!'image' == substr($post->post_mime_type, 0, 5))
274 + if ('image' !== substr($post->post_mime_type, 0, 5))
246 275 return;
247 276
248 277 if ($this->task_exists($post_id))
249 278 return;
250 -
251 - $options = array(
252 - 'attachment_id' => $post_id,
253 - 'blog_id' => get_current_blog_id(),
254 - 'image_quality' => $this->options->get_option('image_quality', 92),
255 - 'keep_original' => $this->options->get_option('back_up_original', true),
256 - 'preserve_exif' => $this->options->get_option('preserve_exif', true),
257 - 'lossy_compression' => $this->options->get_option('lossy_compression', false)
258 - );
259 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 +
260 283 if (filesize($file) > 5242880) {
261 - $options['request_timeout'] = 180;
284 + $task_options['request_timeout'] = 180;
262 285 }
263 286
264 287 $server = $this->options->get_option('compression_server', $this->webservice);
265 288 $task_name = $this->get_associated_task($server);
@@ -264,11 +287,11 @@
264 287 $server = $this->options->get_option('compression_server', $this->webservice);
265 288 $task_name = $this->get_associated_task($server);
266 289
267 290 $blog_info = is_multisite() ? ', blog ID : '.get_current_blog_id() : '';
268 - $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());
269 292
270 - $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);
271 294
272 295 if ($task) $this->set_task_logger($task);
273 296 $this->log($description);
274 297
@@ -315,14 +338,14 @@
315 338 * @param int $image - ID of image
316 339 * @param array $options - options to use
317 340 * @param string $server - the server to process with
318 341 *
319 - * @return boolean - Status of the task
342 + * @return bool | WP_Error - Status of the task
320 343 */
321 344 public function compress_single_image($image, $options, $server) {
322 345 $task_name = $this->get_associated_task($server);
323 346 $blog_info = is_multisite() ? ', blog ID : '.get_current_blog_id() : '';
324 - $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());
325 348
326 349 $task = call_user_func(array($task_name, 'create_task'), 'smush', $description, $options, $task_name);
327 350 if ($task) $this->set_task_logger($task);
328 351 $this->clear_cached_data();
@@ -344,9 +367,9 @@
344 367 */
345 368 public function restore_single_image($image_id, $blog_id) {
346 369
347 370 $switched_blog = false;
348 - if (is_multisite() && current_user_can('manage_network_options')) {
371 + if (is_multisite() && WP_Optimize()->current_user_can('manage_network_options')) {
349 372 switch_to_blog($blog_id);
350 373 $switched_blog = true;
351 374 } elseif (is_multisite() && get_current_blog_id() != $blog_id) {
352 375 return new WP_Error('restore_backup_wrong_blog_id', __('The blog ID provided does not match the current blog.', 'wp-optimize'));
@@ -354,15 +377,23 @@
354 377
355 378 $error = false;
356 379
357 380 $image_path = get_attached_file($image_id);
358 - $backup_path = get_post_meta($image_id, 'original-file', true);
359 -
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 +
360 394 // If the file doesn't exist, check if it's relative
361 395 if (!is_file($backup_path)) {
362 - $uploads_dir = wp_upload_dir();
363 - $uploads_basedir = trailingslashit($uploads_dir['basedir']);
364 -
365 396 if (is_file($uploads_basedir . $backup_path)) {
366 397 $backup_path = $uploads_basedir . $backup_path;
367 398 }
368 399 }
@@ -391,17 +422,27 @@
391 422 $backup_path = $uploads_basedir . $backup_path;
392 423 }
393 424 }
394 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 +
395 435 if (!is_file($backup_path)) {
396 436 // Delete information about backup.
397 - delete_post_meta($image_id, 'original-file');
437 + delete_post_meta($image_id, '_wpo-original-file');
398 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'));
399 - } elseif (!is_writable($image_path)) {
400 - $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'));
401 441 } elseif (!copy($backup_path, $image_path)) {
402 - $error = new WP_Error('restore_failed', __('The file could not be copied; check your PHP error logs for details', 'wp-optimize'));
403 - } 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
404 445 $error = new WP_Error('restore_failed', sprintf(__('The backup file %s could not be deleted.', 'wp-optimize'), $backup_path));
405 446 }
406 447
407 448 if (!$error) {
@@ -406,12 +447,12 @@
406 447
407 448 if (!$error) {
408 449 // if backup image deleted successfully
409 450 // then delete from attachment meta associated smush data
410 - delete_post_meta($image_id, 'smush-complete');
411 - delete_post_meta($image_id, 'smush-stats');
412 - delete_post_meta($image_id, 'original-file');
413 - 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');
414 455 }
415 456
416 457 if ($switched_blog) {
417 458 restore_current_blog();
@@ -433,9 +474,9 @@
433 474 *
434 475 * @param bool $restore_backup if true then restore images from backup otherwise just delete meta.
435 476 * @param int $blog_id blog id.
436 477 * @param int $images_limit how many images process per time.
437 - * @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.
438 479 *
439 480 * @return array ['completed' => (bool), 'message' => (string), 'error' => (string)]
440 481 */
441 482 public function bulk_restore_compressed_images($restore_backup, $blog_id = 1, $images_limit = 100, $delete_only_backups_meta = false) {
@@ -454,9 +495,9 @@
454 495 $processed = 0;
455 496
456 497 if ($restore_backup) {
457 498 // get post ids those have backup meta field.
458 - $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);
459 500
460 501 if (!empty($image_ids)) {
461 502 // run restore function for each found image.
462 503 foreach ($image_ids as $image) {
@@ -461,9 +502,9 @@
461 502 // run restore function for each found image.
462 503 foreach ($image_ids as $image) {
463 504 $restore_result = $this->restore_single_image($image['post_id'], $blog_id);
464 505
465 - // 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".
466 507 if (is_wp_error($restore_result) && 'restore_backup_not_found' != $restore_result->get_error_code()) {
467 508 // we need to stop the work as we haven't restored the backup.
468 509 $result['error'] = $restore_result->get_error_message();
469 510 $this->options->delete_option('smush_images_restored');
@@ -476,9 +517,9 @@
476 517
477 518 $images_count = count($image_ids);
478 519
479 520 // if all images processed then set flag completed to true.
480 - if ($processed == $images_count && $images_count < $images_limit) {
521 + if ($processed === $images_count && $images_count < $images_limit) {
481 522 $this->options->delete_option('smush_images_restored');
482 523 $result['completed'] = true;
483 524 } else {
484 525 // save into options total processed count.
@@ -485,10 +526,12 @@
485 526 $processed += $this->options->get_option('smush_images_restored', 0);
486 527 $this->options->update_option('smush_images_restored', $processed);
487 528
488 529 if (is_multisite()) {
489 - $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));
490 532 } else {
533 + // translators: %s is the number of restored images.
491 534 $result['message'] = sprintf(__('%s compressed images were restored from their backup', 'wp-optimize'), $processed);
492 535 }
493 536 }
494 537
@@ -498,22 +541,26 @@
498 541 }
499 542
500 543 if ($result['completed']) {
501 544
502 - $smushed_images_count = $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->postmeta} WHERE meta_key='smush-complete' AND meta_value=1");
545 + $smushed_images_count = $wpdb->get_var("SELECT COUNT(*) FROM `{$wpdb->postmeta}` WHERE meta_key='_wpo-smush-complete' AND meta_value=1");
503 546 $result['smushed_images_count'] = $smushed_images_count;
504 547
505 548 if ($delete_only_backups_meta) {
506 549 if (is_multisite()) {
507 550 if ($smushed_images_count > 0) {
551 + // translators: %s is the site url
508 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
509 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);
510 555 } else {
556 + // translators: %s is the site url
511 557 $result['message'] = sprintf(__('All the compressed images for the site %s were successfully restored.', 'wp-optimize'), get_site_url($blog_id));
512 558 }
513 559 } else {
514 560 if ($smushed_images_count > 0) {
515 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
516 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);
517 564 } else {
518 565 $result['message'] = __('All the compressed images were successfully restored.', 'wp-optimize');
519 566 }
@@ -519,8 +566,9 @@
519 566 }
520 567 }
521 568 } else {
522 569 if (is_multisite()) {
570 + // translators: %s is the site url
523 571 $result['message'] = sprintf(__('All the compressed images for the site %s were successfully marked as uncompressed.', 'wp-optimize'), get_site_url($blog_id));
524 572 } else {
525 573 $result['message'] = __('All the compressed images were successfully marked as uncompressed.', 'wp-optimize');
526 574 }
@@ -527,11 +575,11 @@
527 575 }
528 576
529 577 // clear all metas for smushed images after work completed.
530 578 // if $delete_only_backup_meta set to true then all meta fields was deleted in restore_single_image()
531 - // and we don't need delete metas for other images.
579 + // and we don't need to delete metas for other images.
532 580 if (!$delete_only_backups_meta) {
533 - $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');");
534 582 }
535 583 }
536 584
537 585 if (is_multisite()) {
@@ -562,28 +610,20 @@
562 610 'blog_id' => $task->get_option('blog_id')
563 611 );
564 612 }
565 613 }
566 -
614 + $default_task_options = $this->get_smush_options();
567 615 foreach ($images as $image) {
568 616 // Skip if already in the queue
569 617 if (in_array($image, $queued_images)) continue;
570 618
571 - $options = array(
572 - 'attachment_id' => intval($image['attachment_id']),
573 - 'blog_id' => intval($image['blog_id']),
574 - 'image_quality' => $this->options->get_option('image_quality', 92),
575 - 'keep_original' => $this->options->get_option('back_up_original', true),
576 - 'preserve_exif' => $this->options->get_option('preserve_exif', true),
577 - 'lossy_compression' => $this->options->get_option('lossy_compression', false)
578 - );
579 -
619 + $task_options = array_merge($default_task_options, array('attachment_id' => intval($image['attachment_id']), 'blog_id' => intval($image['blog_id'])));
580 620 $server = $this->options->get_option('compression_server', $this->webservice);
581 621 $task_name = $this->get_associated_task($server);
582 622
583 623 $blog_info = is_multisite() ? ', Blog ID : '.intval($image['blog_id']) : '';
584 - $description = "$task_name - Attachment ID : ". intval($image['attachment_id']) . $blog_info . ", Started on : ". date("F d, Y h:i:s", time());
585 - $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);
586 626 if ($task) $this->set_task_logger($task);
587 627 }
588 628
589 629 $this->process_smush_tasks();
@@ -636,19 +676,19 @@
636 676 */
637 677 public function record_stats($task) {
638 678
639 679 $attachment_id = $task->get_option('attachment_id');
640 - $completed_task_count = $this->options->get_option('completed_task_count', false);
680 + $completed_task_count = $this->options->get_option('completed_task_count');
641 681 $failed_task_count = $this->options->get_option('failed_task_count', 0);
642 - $total_bytes_saved = $this->options->get_option('total_bytes_saved', false);
682 + $total_bytes_saved = $this->options->get_option('total_bytes_saved');
643 683 $total_percent_saved = $this->options->get_option('total_percent_saved', 0);
644 684
645 - if ('ud_task_failed' == current_action()) {
685 + if ('ud_task_failed' === current_action()) {
646 686 $this->options->update_option('failed_task_count', ++$failed_task_count);
647 687 return;
648 688 }
649 689
650 - if (false === $completed_task_count) {
690 + if (empty($completed_task_count)) {
651 691 $completed_task_count = $total_bytes_saved = 0;
652 692 }
653 693
654 694 if (!$total_bytes_saved) {
@@ -656,12 +696,12 @@
656 696 }
657 697
658 698 if (is_multisite()) {
659 699 switch_to_blog($task->get_option('blog_id', 1));
660 - $stats = get_post_meta($attachment_id, 'smush-stats', true);
700 + $stats = get_post_meta($attachment_id, '_wpo-smush-stats', true);
661 701 restore_current_blog();
662 702 } else {
663 - $stats = get_post_meta($attachment_id, 'smush-stats', true);
703 + $stats = get_post_meta($attachment_id, '_wpo-smush-stats', true);
664 704 }
665 705
666 706 if (isset($stats['sizes-info'])) {
667 707
@@ -674,11 +714,11 @@
674 714 }
675 715
676 716 $percent = round((($original_size - $compressed_size) / $original_size * 100), 2);
677 717 } else {
678 - $original_size = isset($stats['original-size']) ? $stats['original-size'] : 0;
679 - $compressed_size = isset($stats['smushed-size']) ? $stats['smushed-size'] : 0;
680 - $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;
681 721 }
682 722
683 723 $saved = $original_size - $compressed_size;
684 724 $completed_task_count++;
@@ -701,16 +741,17 @@
701 741 if (empty($smush_options)) {
702 742 $smush_options = array(
703 743 'compression_server' => $this->options->get_option('compression_server', $this->get_default_webservice()),
704 744 'image_quality' => $this->options->get_option('image_quality', 92),
705 - '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
706 747 'back_up_original' => $this->options->get_option('back_up_original', true),
707 748 'back_up_delete_after' => $this->options->get_option('back_up_delete_after', true),
708 749 'back_up_delete_after_days' => $this->options->get_option('back_up_delete_after_days', 50),
709 750 'preserve_exif' => $this->options->get_option('preserve_exif', false),
710 - 'autosmush' => $this->options->get_option('autosmush', false),
711 - 'show_smush_metabox' => $this->options->get_option('show_smush_metabox', 'show') == 'show' ? true : false,
712 - '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')
713 754 );
714 755 }
715 756 return $smush_options;
716 757 }
@@ -715,20 +756,29 @@
715 756 return $smush_options;
716 757 }
717 758
718 759 /**
719 - * Updates global smush options
760 + * Update smush options
761 + * Only options whose values differ from the stored values are updated.
720 762 *
721 - * @param array $options - sent in via AJAX
722 - * @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.
723 766 */
724 767 public function update_smush_options($options) {
725 -
768 + $success = true;
726 769 foreach ($options as $option => $value) {
727 - $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 + }
728 779 }
729 -
730 - return true;
780 + return $success;
731 781 }
732 782
733 783 /**
734 784 * Clears smush related stats
@@ -749,8 +799,10 @@
749 799 *
750 800 * @return array - translations used in JS
751 801 */
752 802 public function smush_js_translations() {
803 + $resmushit_article_link = WP_Optimize()->wp_optimize_url('https://resmush.it/api/', __('resmushIt', 'wp-optimize'), '', '', true);
804 +
753 805 return apply_filters('updraft_smush_js_translations', array(
754 806 'all_images_compressed' => __('No uncompressed images were found.', 'wp-optimize'),
755 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'),
756 808 'compress_single_image_dialog' => __('Please wait: compressing the selected image.', 'wp-optimize'),
@@ -756,9 +808,14 @@
756 808 'compress_single_image_dialog' => __('Please wait: compressing the selected image.', 'wp-optimize'),
757 809 'error_try_again_later' => __('Please try again later.', 'wp-optimize'),
758 810 'server_check' => __('Connecting to the Smush API server, please wait', 'wp-optimize'),
759 811 'please_wait' => __('Please wait while the request is being processed', 'wp-optimize'),
760 - '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'),
761 818 'please_select_images' => __('Please select the images you want compressed from the "Uncompressed images" panel first', 'wp-optimize'),
762 819 'please_updating_images_info' => __('Please wait: updating information about the selected image.', 'wp-optimize'),
763 820 'please_select_compressed_images' => __('Please select the images you want to mark as already compressed from the "Uncompressed images" panel first', 'wp-optimize'),
764 821 'view_image' => __('View Image', 'wp-optimize'),
@@ -770,8 +827,12 @@
770 827 'webp_conversion_tool_how_to' => __('How to get the WebP conversion tools to work?', 'wp-optimize'),
771 828 'more' => __('More', 'wp-optimize'),
772 829 'less' => __('Less', 'wp-optimize'),
773 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'),
774 835 ));
775 836 }
776 837
777 838 /**
@@ -796,14 +857,14 @@
796 857 * @param WP_Post $post - a post object
797 858 */
798 859 public function render_smush_metabox($post) {
799 860
800 - $compressed = get_post_meta($post->ID, 'smush-complete', true) ? true : false;
801 - $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);
802 863
803 - $smush_info = get_post_meta($post->ID, 'smush-info', true);
804 - $smush_stats = get_post_meta($post->ID, 'smush-stats', true);
805 - $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');
806 867
807 868 $options = Updraft_Smush_Manager()->get_smush_options();
808 869
809 870 $file = get_attached_file($post->ID);
@@ -812,18 +873,20 @@
812 873 $file_size = ($file && is_file($file)) ? filesize($file) : 0;
813 874
814 875 $extract = array(
815 876 'post_id' => $post->ID,
816 - 'smush_display' => $compressed ? "style='display:none;'" : "style='display:block;'",
817 - 'restore_display' => $compressed ? "style='display:block;'" : "style='display:none;'",
818 - 'restore_action' => $has_backup ? "style='display:block;'" : "style='display:none;'",
819 - 'smush_mark' => !$compressed && !$marked ? "style='display:block;'" : "style='display:none;'",
820 - 'smush_unmark' => $marked ? "style='display:block;'" : "style='display:none;'",
821 - '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 ?: ' ',
822 883 'file_size' => $file_size,
823 884 'smush_options' => $options,
824 885 'custom' => 90 >= $options['image_quality'] && 65 <= $options['image_quality'],
825 886 'smush_details' => '',
887 + 'restore_tooltip' => $this->get_restore_image_tooltip_text(),
888 + 'smush_marked' => $marked,
826 889 );
827 890
828 891 if (!empty($smush_stats['sizes-info'])) {
829 892 $extract['smush_details'] = WP_Optimize()->include_template('images/smush-details.php', true, array('sizes_info' => $smush_stats['sizes-info']));
@@ -828,17 +891,31 @@
828 891 if (!empty($smush_stats['sizes-info'])) {
829 892 $extract['smush_details'] = WP_Optimize()->include_template('images/smush-details.php', true, array('sizes_info' => $smush_stats['sizes-info']));
830 893 }
831 894
895 + $extract['smush_settings_form'] = WP_Optimize()->include_template('admin-metabox-smush-settings.php', true, $extract);
832 896 $extract['compressed_by_another_plugin'] = $this->is_image_compressed_by_another_plugin($post->ID);
833 897 if (WPO_Image_Utils::is_supported_extension($ext, $allowed_extensions)) {
834 898 WP_Optimize()->include_template('admin-metabox-smush.php', false, $extract);
835 899 } else {
836 - 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'));
837 901 }
838 902 }
839 903
840 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 + /**
841 918 * Check if a single image compressed by another plugin.
842 919 *
843 920 * @param int $image_id
844 921 * @return bool
@@ -844,10 +921,11 @@
844 921 * @return bool
845 922 */
846 923 private function is_image_compressed_by_another_plugin($image_id) {
847 924 global $wpdb;
925 + static $is_ewwwio_images_table_exists = null;
848 926
849 - $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);
850 928
851 929 if (is_array($meta)) {
852 930 foreach ($meta as $row) {
853 931 // Smush, Imagify, Compress JPEG & PNG images by TinyPNG.
@@ -852,16 +930,18 @@
852 930 foreach ($meta as $row) {
853 931 // Smush, Imagify, Compress JPEG & PNG images by TinyPNG.
854 932 if (in_array($row['meta_key'], array('wp-smpro-smush-data', '_imagify_optimization_level', 'tiny_compress_images'))) return true;
855 933 // ShortPixel Image Optimizer
856 - 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;
857 935 }
858 936 }
859 937
860 - 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) {
861 941 $old_show_errors = $wpdb->show_errors(false);
862 942 // EWWW Image Optimizer.
863 - $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));
864 944 if (!empty($ewww_image)) return true;
865 945 $wpdb->show_errors($old_show_errors);
866 946 }
867 947
@@ -880,15 +960,15 @@
880 960
881 961 if (!WP_Optimize()->get_db_info()->table_exists('ewwwio_images')) return $args;
882 962
883 963 $old_show_errors = $wpdb->show_errors(false);
884 - $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'");
885 965 $wpdb->show_errors($old_show_errors);
886 966
887 967 if (isset($args['post__not_in'])) {
888 - $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
889 969 } else {
890 - $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
891 971 }
892 972
893 973 return $args;
894 974 }
@@ -899,11 +979,11 @@
899 979 * @param string $use_cache
900 980 * @return array - uncompressed images
901 981 */
902 982 public function get_uncompressed_images($use_cache = "true") {
903 - if ("true" == $use_cache) {
983 + if ("true" === $use_cache) {
904 984 $uncompressed_images = $this->get_from_cache('uncompressed_images');
905 - if ($uncompressed_images) return $uncompressed_images;
985 + if ($uncompressed_images && is_array($uncompressed_images)) return $uncompressed_images;
906 986 }
907 987
908 988 $uncompressed_images = array();
909 989 $accepted_mimes = array('image/jpeg', 'image/gif', 'image/png');
@@ -944,12 +1024,12 @@
944 1024 'thumb_url' => wp_get_attachment_thumb_url($image_id),
945 1025 'filesize' => filesize(get_attached_file($image_id))
946 1026 );
947 1027 } else {
948 - $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.");
949 1029 }
950 1030 } else {
951 - $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");
952 1032 }
953 1033 }
954 1034
955 1035 restore_current_blog();
@@ -972,12 +1052,12 @@
972 1052 'thumb_url' => wp_get_attachment_thumb_url($image_id),
973 1053 'filesize' => filesize(get_attached_file($image_id))
974 1054 );
975 1055 } else {
976 - $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.");
977 1057 }
978 1058 } else {
979 - $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");
980 1060 }
981 1061 }
982 1062 }
983 1063
@@ -1052,13 +1132,13 @@
1052 1132 $stats = array();
1053 1133
1054 1134 foreach ($images as $image) {
1055 1135 if (is_multisite()) {
1056 - switch_to_blog($image['blog_id'], 1);
1057 - $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';
1058 1138 restore_current_blog();
1059 1139 } else {
1060 - $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';
1061 1141 }
1062 1142 }
1063 1143
1064 1144 return array_count_values($stats);
@@ -1066,9 +1146,9 @@
1066 1146
1067 1147 /**
1068 1148 * Returns a list of images for smush (from cache if available)
1069 1149 *
1070 - * @return array - List of task objects with uncompressed images
1150 + * @return array|mixed - List of task objects with uncompressed images
1071 1151 */
1072 1152 public function get_pending_tasks() {
1073 1153 return $this->get_active_tasks('smush');
1074 1154 }
@@ -1074,8 +1154,10 @@
1074 1154 }
1075 1155
1076 1156 /**
1077 1157 * Deletes and removes any pending tasks from queue
1158 + *
1159 + * @return bool
1078 1160 */
1079 1161 public function clear_pending_images() {
1080 1162
1081 1163 $pending_tasks = $this->get_active_tasks('smush');
@@ -1111,9 +1193,9 @@
1111 1193
1112 1194 $enqueue_version = WP_Optimize()->get_enqueue_version();
1113 1195 $min_or_not = WP_Optimize()->get_min_or_not_string();
1114 1196 $min_or_not_internal = WP_Optimize()->get_min_or_not_internal_string();
1115 -
1197 +
1116 1198 $js_variables = $this->smush_js_translations();
1117 1199 $js_variables['ajaxurl'] = admin_url('admin-ajax.php');
1118 1200 $js_variables['features'] = $this->get_features();
1119 1201
@@ -1123,8 +1205,9 @@
1123 1205 $js_variables['compress'] = esc_html__('Compress', 'wp-optimize');
1124 1206 $js_variables['cancel'] = esc_html__('Cancel', 'wp-optimize');
1125 1207 $js_variables['cancelling'] = esc_html__('Cancelling...', 'wp-optimize');
1126 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');
1127 1210
1128 1211 wp_enqueue_script('block-ui-js', WPO_PLUGIN_URL.'includes/blockui/jquery.blockUI'.$min_or_not.'.js', array('jquery'), $enqueue_version);
1129 1212 wp_enqueue_script('wp-optimize-heartbeat-js', WPO_PLUGIN_URL.'js/heartbeat'.$min_or_not_internal.'.js', array('jquery'), $enqueue_version);
1130 1213 wp_localize_script('wp-optimize-heartbeat-js', 'wpo_heartbeat_ajax', array(
@@ -1131,9 +1214,9 @@
1131 1214 'ajaxurl' => admin_url('admin-ajax.php'),
1132 1215 'nonce' => wp_create_nonce('heartbeat-nonce'),
1133 1216 'interval' => WPO_Ajax::HEARTBEAT_INTERVAL
1134 1217 ));
1135 - wp_enqueue_script('smush-js', WPO_PLUGIN_URL.'js/wposmush'.$min_or_not_internal.'.js', array('jquery', 'block-ui-js', 'wp-optimize-send-command', 'wp-optimize-heartbeat-js'), $enqueue_version);
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);
1136 1219 wp_enqueue_style('smush-css', WPO_PLUGIN_URL.'css/smush'.$min_or_not_internal.'.css', array(), $enqueue_version);
1137 1220 wp_localize_script('smush-js', 'wposmush', $js_variables);
1138 1221 }
1139 1222
@@ -1184,9 +1267,9 @@
1184 1267
1185 1268 /**
1186 1269 * Gets allowed service providers for smush
1187 1270 *
1188 - * @return array - key value pair of service name => task name
1271 + * @return array - A pair of key/value. e.g. service name => task name
1189 1272 */
1190 1273 public function get_allowed_services() {
1191 1274 return array(
1192 1275 'resmushit' => 'Re_Smush_It_Task',
@@ -1193,11 +1276,32 @@
1193 1276 );
1194 1277 }
1195 1278
1196 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 + /**
1197 1301 * Gets allowed service provider features smush
1198 1302 *
1199 - * @return array - key value pair of service name => features exposed
1303 + * @return array - A pair of key/value. e.g. service name => features exposed
1200 1304 */
1201 1305 public function get_features() {
1202 1306 $features = array();
1203 1307 foreach ($this->get_allowed_services() as $service => $class_name) {
@@ -1216,27 +1320,19 @@
1216 1320 }
1217 1321
1218 1322 /**
1219 1323 * Delete all smush log files
1324 + *
1325 + * @deprecated 3.5.0
1220 1326 */
1221 1327 public function delete_log_files() {
1222 - if (!function_exists('glob')) return;
1223 - $upload_dir = wp_get_upload_dir();
1224 - $upload_base = $upload_dir['basedir'];
1225 - $files = glob($upload_base . '/smush-*.log');
1226 - if (false === $files) return;
1227 - foreach ($files as $file) {
1228 - if (is_file($file)) {
1229 - @unlink($file); // phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- suppress error due to file permission issues
1230 - }
1231 - }
1232 -
1328 + _deprecated_function(__METHOD__, '3.5.0');
1233 1329 }
1234 1330
1235 1331 /**
1236 1332 * Adds a logger to the task
1237 1333 *
1238 - * @param Mixed $task - a task object
1334 + * @param mixed $task - a task object
1239 1335 */
1240 1336 public function set_task_logger($task) {
1241 1337 if (!$this->logger) {
1242 1338 $this->logger = new Updraft_File_Logger($this->get_logfile_path());
@@ -1269,9 +1365,9 @@
1269 1365 $log_header = array();
1270 1366
1271 1367 // phpcs:enable
1272 1368 $log_header[] = "\n";
1273 - $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();
1274 1370 $log_header[] = "WP: ".$wp_version;
1275 1371 $php_uname = '';
1276 1372 if (function_exists('php_uname')) {
1277 1373 $php_uname = ", " . php_uname();
@@ -1278,9 +1374,9 @@
1278 1374 }
1279 1375 $log_header[] = "PHP: ".phpversion()." (".PHP_SAPI.$php_uname.")";
1280 1376 $log_header[] = "MySQL: $mysql_version";
1281 1377 $log_header[] = "WPLANG: ".get_locale();
1282 - $log_header[] = "Server: ".$_SERVER["SERVER_SOFTWARE"];
1378 + $log_header[] = "Server: ". TeamUpdraft\WP_Optimize\Includes\Fragments\fetch_superglobal('server', 'SERVER_SOFTWARE', 'string', 'sanitize_text_field', '-');
1283 1379 $log_header[] = "Outbound connections: ".(defined('WP_HTTP_BLOCK_EXTERNAL') ? 'Y' : 'N');
1284 1380 $log_header[] = "Disabled Functions: $disabled_functions";
1285 1381 $log_header[] = "max_execution_time: $max_execution_time";
1286 1382 $log_header[] = "memory_limit: $memory_limit (used: {$memory_usage}M | {$total_memory_usage}M)";
@@ -1292,12 +1388,12 @@
1292 1388 $this->log($log_entry);
1293 1389 }
1294 1390 }
1295 1391
1296 - $memlim = $this->memory_check_current();
1392 + $memory_limit = $this->memory_check_current();
1297 1393
1298 - if ($memlim<65 && $memlim>0) {
1299 - $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');
1300 1396 }
1301 1397
1302 1398 if ($max_execution_time>0 && $max_execution_time<20) {
1303 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');
@@ -1314,9 +1410,9 @@
1314 1410
1315 1411 /**
1316 1412 * Get the WordPress version
1317 1413 *
1318 - * @return String - the version
1414 + * @return string - the version
1319 1415 */
1320 1416 public function get_wordpress_version() {
1321 1417 static $got_wp_version = false;
1322 1418
@@ -1321,9 +1417,9 @@
1321 1417 static $got_wp_version = false;
1322 1418
1323 1419 if (!$got_wp_version) {
1324 1420 global $wp_version;
1325 - @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
1326 1422 $got_wp_version = $wp_version;
1327 1423 }
1328 1424
1329 1425 return $got_wp_version;
@@ -1331,16 +1427,18 @@
1331 1427
1332 1428 /**
1333 1429 * Get the current memory limit
1334 1430 *
1335 - * @return String - memory limit in megabytes
1431 + * @param ?string $memory_limit Memory limit in megabytes
1432 + *
1433 + * @return string - memory limit in megabytes
1336 1434 */
1337 - public function memory_check_current($memory_limit = false) {
1435 + public function memory_check_current($memory_limit = null) {
1338 1436 // Returns in megabytes
1339 - if (false == $memory_limit) $memory_limit = ini_get('memory_limit');
1437 + if (empty($memory_limit)) $memory_limit = ini_get('memory_limit');
1340 1438 $memory_limit = rtrim($memory_limit);
1341 1439 $memory_unit = $memory_limit[strlen($memory_limit)-1];
1342 - if (0 == (int) $memory_unit && '0' !== $memory_unit) {
1440 + if (0 === (int) $memory_unit && '0' !== $memory_unit) {
1343 1441 $memory_limit = substr($memory_limit, 0, strlen($memory_limit)-1);
1344 1442 } else {
1345 1443 $memory_unit = '';
1346 1444 }
@@ -1423,11 +1521,11 @@
1423 1521 global $wpdb;
1424 1522
1425 1523 // get list of cached data by optimization.
1426 1524 if ($this->is_multisite_mode()) {
1427 - $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_%'");
1428 1526 } else {
1429 - $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_%'");
1430 1528 }
1431 1529
1432 1530 if (!empty($keys)) {
1433 1531 $transient_keys = array();
@@ -1467,19 +1565,19 @@
1467 1565 $year = (int) $match[1];
1468 1566 $month = (int) $match[2];
1469 1567
1470 1568 $limit = strtotime('-'.$days_ago.' '.(($days_ago > 1) ? 'days' : 'day'));
1471 - $year_limit = (int) date('Y', $limit);
1472 - $month_limit = (int) date('m', $limit);
1473 - $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);
1474 1572
1475 1573 // if current directory is newer than needed then we skip it.
1476 - if ($year_limit < $year || ($year_limit == $year && $month_limit < $month)) {
1574 + if ($year_limit < $year || ($year_limit === $year && $month_limit < $month)) {
1477 1575 return;
1478 1576 }
1479 1577
1480 1578 // we will check dates only in directory that contain limit date.
1481 - $check_date = ($year_limit == $year && $month_limit == $month);
1579 + $check_date = ($year_limit === $year && $month_limit === $month);
1482 1580 }
1483 1581
1484 1582 // GLOB_BRACE isn't defined on some systems (Solaris, SunOS and more) > https://www.php.net/manual/en/function.glob.php
1485 1583 $files = glob($directory . '*-updraft-pre-smush-original.*', (defined('GLOB_BRACE') ? GLOB_BRACE : 0));
@@ -1485,13 +1583,13 @@
1485 1583 $files = glob($directory . '*-updraft-pre-smush-original.*', (defined('GLOB_BRACE') ? GLOB_BRACE : 0));
1486 1584
1487 1585 foreach ($files as $file) {
1488 1586 if ($check_date) {
1489 - $filedate_day = (int) date('j', filectime($file));
1587 + $filedate_day = (int) gmdate('j', filectime($file));
1490 1588 if ($filedate_day >= $day_limit) continue;
1491 1589 }
1492 1590
1493 - unlink($file);
1591 + wp_delete_file($file);
1494 1592 }
1495 1593
1496 1594 } else {
1497 1595 // scan directories recursively.
@@ -1502,9 +1600,9 @@
1502 1600 $file = readdir($handle);
1503 1601
1504 1602 while (false !== $file) {
1505 1603
1506 - if ('.' == $file || '..' == $file) {
1604 + if ('.' === $file || '..' === $file) {
1507 1605 $file = readdir($handle);
1508 1606 continue;
1509 1607 }
1510 1608
@@ -1512,9 +1610,9 @@
1512 1610 $this->clear_backup_images_directory($directory . $file, $days_ago);
1513 1611 } elseif (is_file($directory . $file) && preg_match('/^.+-updraft-pre-smush-original\.\S{3,4}/i', $file)) {
1514 1612 // check the file time and compare with $days_ago.
1515 1613 $filedate_day = (int) filectime($directory . $file);
1516 - 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);
1517 1615 }
1518 1616
1519 1617 $file = readdir($handle);
1520 1618 }
@@ -1525,9 +1623,9 @@
1525 1623 /**
1526 1624 * Clean backup smush images according to saved options.
1527 1625 */
1528 1626 public function clear_backup_images() {
1529 - $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');
1530 1628
1531 1629 if (!$back_up_delete_after) return;
1532 1630
1533 1631 $back_up_delete_after_days = $this->options->get_option('back_up_delete_after_days', 50);
@@ -1545,48 +1643,12 @@
1545 1643 *
1546 1644 * @return bool
1547 1645 */
1548 1646 public function is_compressed($attachment_id) {
1549 - return (true == get_post_meta($attachment_id, 'smush-complete', true));
1647 + return (true === (bool) get_post_meta($attachment_id, '_wpo-smush-complete', true));
1550 1648 }
1551 1649
1552 1650 /**
1553 - * @param array $form_fields
1554 - * @param WP_Post $post
1555 - *
1556 - * @return array
1557 - */
1558 - public function add_compress_button_to_media_modal($form_fields, $post) {
1559 -
1560 - if (!is_admin() || !function_exists('get_current_screen')) return $form_fields;
1561 -
1562 - /**
1563 - * In media modal get_current_screen() return null or id = 'async-upload' We don't need add smush fields elsewhere.
1564 - */
1565 - $current_screen = get_current_screen();
1566 - if (null !== $current_screen && 'async-upload' != $current_screen->id) return $form_fields;
1567 -
1568 - /**
1569 - * Don't show additional fields for non-image attachments.
1570 - */
1571 - if (!wp_attachment_is_image($post->ID)) return $form_fields;
1572 -
1573 - ob_start();
1574 - $this->render_smush_metabox($post);
1575 - $smush_metabox = ob_get_contents();
1576 - ob_end_clean();
1577 -
1578 - $form_fields['wpo_compress_image'] = array(
1579 - 'value' => '',
1580 - 'label' => __('Compress image', 'wp-optimize'),
1581 - 'input' => 'html',
1582 - 'html' => $smush_metabox,
1583 - );
1584 -
1585 - return $form_fields;
1586 - }
1587 -
1588 - /**
1589 1651 * Returns true if multisite
1590 1652 *
1591 1653 * @return bool
1592 1654 */
@@ -1599,13 +1661,20 @@
1599 1661 *
1600 1662 * @param int $post_id - WordPress Post ID
1601 1663 */
1602 1664 public function unscheduled_original_file_deletion($post_id) {
1603 - $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 + }
1604 1670 $uploads_dir = wp_get_upload_dir();
1605 - $the_original_file = trailingslashit($uploads_dir['basedir']) . $the_original_file;
1606 - if ('' != $the_original_file && file_exists($the_original_file)) {
1607 - @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);
1608 1677 }
1609 1678 }
1610 1679
1611 1680 /**
@@ -1644,14 +1713,14 @@
1644 1713 'relation' => 'AND',
1645 1714 array(
1646 1715 'relation' => 'OR',
1647 1716 array(
1648 - 'key' => 'smush-complete',
1717 + 'key' => '_wpo-smush-complete',
1649 1718 'compare' => '!=',
1650 1719 'value' => '1',
1651 1720 ),
1652 1721 array(
1653 - 'key' => 'smush-complete',
1722 + 'key' => '_wpo-smush-complete',
1654 1723 'compare' => 'NOT EXISTS',
1655 1724 'value' => '',
1656 1725 ),
1657 1726 ),
@@ -1696,9 +1765,9 @@
1696 1765 }
1697 1766 }
1698 1767
1699 1768 /**
1700 - * Returns a Updraft_Smush_Manager instance
1769 + * Returns Updraft_Smush_Manager instance
1701 1770 */
1702 1771 function Updraft_Smush_Manager() {
1703 1772 return Updraft_Smush_Manager::instance();
1704 1773 }